Перейти к содержимому

Pageyoffset устарело чем заменить

  • автор:

Координаты в документе

Материал на этой странице устарел, поэтому скрыт из оглавления сайта.

Более новая информация по этой теме находится на странице https://learn.javascript.ru/coordinates.

Система координат относительно страницы или, иначе говоря, относительно документа, начинается в левом-верхнем углу, но не окна, а именно страницы.

И координаты в ней означают позицию по отношению не к окну браузера, а к документу в целом.

Если провести аналогию с CSS, то координаты относительно окна – это position:fixed , а относительно документа – position:absolute (при позиционировании вне других элементов, естественно).

Мы будем называть координаты в ней pageX/pageY .

Они нужны в первую очередь для того, чтобы показывать элемент в определённом месте страницы, а не окна.

Сравнение систем координат

Когда страница не прокручена, точки начала координат относительно окна (clientX,clientY) и документа (pageX,pageY) совпадают:

Например, координаты элемента с надписью «STANDARDS» равны расстоянию от верхней/левой границы окна:

Прокрутим страницу, чтобы элемент был на самом верху:

Посмотрите на рисунок ниже, на нём – та же страница, только прокрученная, и тот же элемент «STANDARDS».

  • Координата clientY изменилась. Она была 175 , а стала 0 , так как элемент находится вверху окна.
  • Координата pageY осталась такой же, так как отсчитывается от левого-верхнего угла документа.

Итак, координаты pageX/pageY не меняются при прокрутке, в отличие от clientX/clientY .

Получение координат

К сожалению, готовой функции для получения координат элемента относительно страницы нет. Но её можно легко написать самим.

Эти две системы координат жёстко связаны: pageY = clientY + текущая вертикальная прокрутка .

Наша функция getCoords(elem) будет брать результат elem.getBoundingClientRect() и прибавлять текущую прокрутку документа.

Результат getCoords : объект с координатами

function getCoords(elem) < // кроме IE8- var box = elem.getBoundingClientRect(); return < top: box.top + pageYOffset, left: box.left + pageXOffset >; >

Если нужно поддерживать более старые IE, то вот альтернативный, самый кросс-браузерный вариант:

function getCoords(elem) < // (1) var box = elem.getBoundingClientRect(); var body = document.body; var docEl = document.documentElement; // (2) var scrollTop = window.pageYOffset || docEl.scrollTop || body.scrollTop; var scrollLeft = window.pageXOffset || docEl.scrollLeft || body.scrollLeft; // (3) var clientTop = docEl.clientTop || body.clientTop || 0; var clientLeft = docEl.clientLeft || body.clientLeft || 0; // (4) var top = box.top + scrollTop - clientTop; var left = box.left + scrollLeft - clientLeft; return < top: top, left: left >; >

Разберём что и зачем, по шагам:

  1. Получаем прямоугольник.
  2. Считаем прокрутку страницы. Все браузеры, кроме IE8- поддерживают свойство pageXOffset/pageYOffset . В более старых IE, когда установлен DOCTYPE, прокрутку можно получить из documentElement , ну и наконец если DOCTYPE некорректен – использовать body .
  3. В IE документ может быть смещён относительно левого верхнего угла. Получим это смещение.
  4. Добавим прокрутку к координатам окна и вычтем смещение html/body , чтобы получить координаты нужного нам элемента.

Устаревший метод: offset*

Есть альтернативный способ нахождения координат – это пройти всю цепочку offsetParent от элемента вверх и сложить отступы offsetLeft/offsetTop .

Мы разбираем его здесь с учебной целью, так как он используется лишь в старых браузерах.

Вот функция, реализующая такой подход.

function getOffsetSum(elem) < var top = 0, left = 0; while (elem) < top = top + parseInt(elem.offsetTop); left = left + parseInt(elem.offsetLeft); elem = elem.offsetParent; >return < top: top, left: left >; >

Казалось бы, код нормальный. И он как-то работает, но разные браузеры преподносят «сюрпризы», включая или выключая размер рамок и прокруток из offsetTop/Left , некорректно учитывая позиционирование. В итоге результат не всегда верен. Можно, конечно, разобрать эти проблемы и посчитать действительно аккуратно и правильно этим способом, но зачем? Ведь есть getBoundingClientRect .

Вы можете увидеть разницу между вычислением координат через offset* и getBoundingClientRect на примере.

В прямоугольнике ниже есть 3 вложенных DIV . Все они имеют border , кое-кто из них имеет position/margin/padding .

Кликните по внутреннему (жёлтому) элементу, чтобы увидеть результаты обоих методов: getOffsetSum и getCoords , а также реальные координаты курсора – event.pageX/pageY (мы обсудим их позже в статье Мышь: IE8-, исправление события).

Кликните, чтобы получить координаты getOffsetSum и getCoords
getOffsetSum: значение getOffsetSum()
getCoords: значение getCoords()
mouse: координаты мыши

При клике на любом месте жёлтого блока вы легко увидите разницу между getOffsetSum(elem) и getCoords(elem) .

Для того, чтобы узнать, какой же результат верный, кликните в левом-верхнем углу жёлтого блока, причём обратите внимание – кликать нужно не на жёлтом, а на чёрном, это рамка, она тоже входит в элемент. Будут видны точные координаты мыши, так что вы можете сравнить их с getOffsetSum/getCoords .

Пример клика в правильном месте (обратите внимание на разницу координат):

Именно getCoords всегда возвращает верное значение.

Координаты на экране screenX/screenY

Есть ещё одна система координат, которая используется очень редко, но для полноты картины необходимо её упомянуть.

Координаты относительно экрана screenX/screenY отсчитываются от его левого-верхнего угла. Имеется в виду именно весь экран, а не окно браузера.

Такие координаты могут быть полезны, например, при работе с мобильными устройствами или для открытия нового окна посередине экрана вызовом window.open.

    Размеры экрана хранятся в глобальной переменной screen:

// общая ширина/высота alert( screen.width + ' x ' + screen.height ); // доступная ширина/высота (за вычетом таскбара и т.п.) alert( screen.availWidth + ' x ' + screen.availHeight ); // есть и ряд других свойств screen (см. документацию)
alert( "Браузер находится на " + window.screenX + "," + window.screenY );

Заметим, что общую информацию об экране и браузере получить можно, а вот координаты конкретного элемента на экране – нельзя, нет аналога getBoundingClientRect или иного метода для этого.

Итого

У любой точки в браузере есть координаты:

  1. Относительно окна window – elem.getBoundingClientRect() .
  2. Относительно документа document – добавляем прокрутку, во всех фреймворках есть готовая функция.
  3. Относительно экрана screen – можно узнать координаты браузера, но не элемента.

Иногда в старом коде можно встретить использование offsetTop/Left для подсчёта координат. Это очень старый и неправильный способ, не стоит его использовать.

Координаты будут нужны нам далее, при работе с событиями мыши (координаты клика) и элементами (перемещение).

Задачи

Область видимости для документа

важность: 5

Напишите функцию getDocumentScroll() , которая возвращает объект с информацией о текущей прокрутке и области видимости.

  • top – координата верхней границы видимой части (относительно документа).
  • bottom – координата нижней границы видимой части (относительно документа).
  • height – полная высота документа, включая прокрутку.

В этой задаче учитываем только вертикальную прокрутку: горизонтальная делается аналогично, а нужна сильно реже.

  • top – это pageYOffset .
  • bottom – это pageYOffset плюс высота видимой части documentElement.clientHeight .
  • height – полная высота документа, её вычисление дано в главе Размеры и прокрутка страницы.
function getDocumentScroll() < var scrollHeight = Math.max( document.body.scrollHeight, document.documentElement.scrollHeight, document.body.offsetHeight, document.documentElement.offsetHeight, document.body.clientHeight, document.documentElement.clientHeight ); return < top: pageYOffset, bottom: pageYOffset + document.documentElement.clientHeight, height: scrollHeight >; >

Разместить заметку внутри элемента

важность: 5

Расширьте предыдущую задачу Покажите заметку около элемента (абсолютное позиционирование): научите функцию positionAt(anchor, position, elem) вставлять elem внутрь anchor .

Новые значения position :

  • top-out , right-out , bottom-out – работают так же, как раньше, то есть вставляют elem над/справа/под anchor .
  • top-in , right-in , bottom-in – вставляют elem внутрь anchor : к верхней границе/правой/нижней.
// покажет note сверху blockquote positionAt(blockquote, "top-out", note); // покажет note сверху-внутри blockquote positionAt(blockquote, "top-in", note);

Альтернатива window.pageYoffset и window.scrollY в Angular4

Насколько мне известно, бегунок находится вне DOM, поэтому его можно прочитать только через 2 вышеуказанных метода. Или я ошибаюсь и есть у Angular свои примочки на этот случай?

Отслеживать
13.7k 12 12 золотых знаков 43 43 серебряных знака 75 75 бронзовых знаков
задан 10 окт 2017 в 13:40
Владимир Смирнов Владимир Смирнов
31 4 4 бронзовых знака

Не знаю что вы подразумеваете под примочками, но вам никто не запрещает в компоненте в любой момент использовать window.pageYoffset . Если он нужен в шаблоне — сделайте например функцию которая его возвращает и используйте ее

>

17 окт 2017 в 13:18

0

Сортировка: Сброс на вариант по умолчанию

Знаете кого-то, кто может ответить? Поделитесь ссылкой на этот вопрос по почте, через Твиттер или Facebook.

  • javascript
  • angular2
  • angular4
    Важное на Мете
Похожие

Подписаться на ленту

Лента вопроса

Для подписки на ленту скопируйте и вставьте эту ссылку в вашу программу для чтения RSS.

Дизайн сайта / логотип © 2024 Stack Exchange Inc; пользовательские материалы лицензированы в соответствии с CC BY-SA . rev 2024.1.3.2953

Нажимая «Принять все файлы cookie» вы соглашаетесь, что Stack Exchange может хранить файлы cookie на вашем устройстве и раскрывать информацию в соответствии с нашей Политикой в отношении файлов cookie.

Чем scrollY отличается от pageYOffset | scrollTop?

Пытаюсь разобраться со скроллом в JS.
Вопрос запутанный, и нету адекватных туториалов где по пунктам все разжуют. Парадокс.

Да, есть документация, но она довольно хардкорна.
Поэтому прошу помощи.

Вот смотрите, два куска кода:

var scrollPosition = window.scrollY

var scrollPosition = window.pageYOffset | document.body.scrollTop

Оба отдают ТОЖЕ САМОЕ в консоль — текущее положение скролла. Так какая же разница?

  • Вопрос задан более трёх лет назад
  • 13189 просмотров

Комментировать
Решения вопроса 1

EreminD

Кое-что умею

The read-only scrollY property of the Window interface returns the number of pixels that the document is currently scrolled vertically

The pageYOffset property is an alias for the scrollY property

An element’s scrollTop value is a measurement of the distance from the element’s top to its topmost visible content

Короче
scrollY — на сколько пикселей страница пролистана вниз
pageYOffset — то ж самое
scrollTop — насколько пикселей пролистано от начала элемента до видимой области

Element.getBoundingClientRect()

Метод Element.getBoundingClientRect() возвращает размер элемента и его позицию относительно viewport (часть страницы, показанная на экране, и которую мы видим).

Синтаксис

domRect = element.getBoundingClientRect();

Возвращаемое значение

Данный метод возвращает объект DOMRect (en-US), который является объединением прямоугольников, возвращаемых методом getClientRects() (en-US) для данного элемента, т. е. CSS border-boxes (css-коробок в рамках), связанных с этим элементом. Результатом является самый маленький прямоугольник, в котором содержится весь элемент с read-only left , top , right , bottom , x , y , width и height свойствами, описывающие это в пикселях. Все свойства, кроме width и height , являются относительными к верхнему левому углу viewport-а.

Explanation of DOMRect values

Пустые border-box полностью игнорируются. Если border-box элемента пуст, прямоугольник возвращается с нулевыми width и height , а top и left берутся у следующего CSS элемента (в порядке контента).

После каждого скролла значения left , top , right и bottom изменяются, так как эти значения относительны к viewport и не абсолютные.

Если вам нужны значения, описывающие прямоугольник относительно к верхнему левому углу документа, просто добавьте к свойствам top и left текущую позицию прокрутки, используя window.scrollX и window.scrollY ), чтобы получить прямоугольник, положение которого не зависит от текущей позиции прокрутки.

Про кроссбраузерность

Скрипты, требующих высокую кроссбраузерность, могут использовать window.pageXOffset (en-US) и window.pageYOffset вместо window.scrollX and window.scrollY . Скрипты без доступа к этим свойствам могут использовать код, наподобие этого:

// Для scrollX (((t = document.documentElement) || (t = document.body.parentNode)) && typeof t.scrollLeft == "number" ? t : document.body ).scrollLeft( // Для scrollY ((t = document.documentElement) || (t = document.body.parentNode)) && typeof t.scrollTop == "number" ? t : document.body, ).scrollTop; 

Пример

// rect - DOMRect объект с 8-ми свойствами: left, top, right, bottom, x, y, width, height var rect = obj.getBoundingClientRect(); 

Спецификации

Specification
CSSOM View Module
# dom-element-getboundingclientrect

Совместимость с браузерами

BCD tables only load in the browser

Смотрите также

  • getClientRects() (en-US)
  • MSDN: getBoundingClientRect
  • MSDN: ClientRect , более ранняя версия DOMRect
  • Element.getClientRects() (en-US)

Found a content problem with this page?

  • Edit the page on GitHub.
  • Report the content issue.
  • View the source on GitHub.

This page was last modified on 3 авг. 2023 г. by MDN contributors.

Your blueprint for a better internet.

MDN

Support

  • Product help
  • Report an issue

Our communities

Developers

  • Web Technologies
  • Learn Web Development
  • MDN Plus
  • Hacks Blog
  • Website Privacy Notice
  • Cookies
  • Legal
  • Community Participation Guidelines

Visit Mozilla Corporation’s not-for-profit parent, the Mozilla Foundation.
Portions of this content are ©1998– 2024 by individual mozilla.org contributors. Content available under a Creative Commons license.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *