- HTML DOM Element offsetTop
- See Also:
- Syntax
- Return Value
- More Examples
- Browser Support
- Координаты в документе
- Сравнение систем координат
- Получение координат
- Устаревший метод: offset*
- Координаты на экране screenX/screenY
- Итого
- Задачи
- Область видимости для документа
- Разместить заметку внутри элемента
- Свойство offsetTop
- Поддержка браузера
- Синтаксис
- Технические детали
- Ещё примеры
- Пример
- Пример
HTML DOM Element offsetTop
All block-level elements report offsets relative to the offset parent:
The offset parent is the nearest ancestor that has a position other than static.
If no offset parent exists, the offset is relative to the document body.
See Also:
Syntax
Return the top offset position:
Return Value
More Examples
Create a sticky navigation bar:
// Get the navbar
const navbar = document.getElementById(«navbar»);
// Get the offset position of the navbar
const sticky = navbar.offsetTop;
// Add the sticky class to the navbar when you reach its scroll position. Remove the sticky class when you leave the scroll position.
function myFunction() if (window.pageYOffset >= sticky) navbar.classList.add(«sticky»)
> else navbar.classList.remove(«sticky»);
>
>
Browser Support
element.offsetTop is supported in all browsers:
Chrome | Edge | Firefox | Safari | Opera | IE |
Yes | Yes | Yes | Yes | Yes | Yes |
Координаты в документе
Материал на этой странице устарел, поэтому скрыт из оглавления сайта.
Более новая информация по этой теме находится на странице 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 : объект с координатами
Если нужно поддерживать более старые IE, то вот альтернативный, самый кросс-браузерный вариант:
Разберём что и зачем, по шагам:
- Получаем прямоугольник.
- Считаем прокрутку страницы. Все браузеры, кроме IE8- поддерживают свойство pageXOffset/pageYOffset . В более старых IE, когда установлен DOCTYPE, прокрутку можно получить из documentElement , ну и наконец если DOCTYPE некорректен – использовать body .
- В IE документ может быть смещён относительно левого верхнего угла. Получим это смещение.
- Добавим прокрутку к координатам окна и вычтем смещение 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(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 или иного метода для этого.
Итого
У любой точки в браузере есть координаты:
- Относительно окна window – elem.getBoundingClientRect() .
- Относительно документа document – добавляем прокрутку, во всех фреймворках есть готовая функция.
- Относительно экрана screen – можно узнать координаты браузера, но не элемента.
Иногда в старом коде можно встретить использование offsetTop/Left для подсчёта координат. Это очень старый и неправильный способ, не стоит его использовать.
Координаты будут нужны нам далее, при работе с событиями мыши (координаты клика) и элементами (перемещение).
Задачи
Область видимости для документа
Напишите функцию 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 >; >
Разместить заметку внутри элемента
Расширьте предыдущую задачу Покажите заметку около элемента (абсолютное позиционирование): научите функцию positionAt(anchor, position, elem) вставлять elem внутрь anchor .
- 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);
Свойство offsetTop
Свойство offsetTop возвращает верхнюю позицию (в пикселях) относительно верхней части элемента offsetParent.
Возвращаемое значение включает в себя:
- верхняя позиция и поле элемента
- верхний отступ, полоса прокрутки и границей элемента offsetParent
Примечание: Элемент offsetParent — это ближайший предок, который имеет позицию, отличную от статической.
Совет: Чтобы вернуть левую позицию элемента, используйте свойство offsetLeft.
Поддержка браузера
Синтаксис
Верните верхнее смещенное положение:
Технические детали
Значение по умолчанию: | нет значения по умолчанию |
---|---|
Вернёт значение | Число, представляющее верхнюю позицию элемента, в пикселях |
DOM Версия: | CSSOM |
Ещё примеры
Пример
Получить положение элемента :
var testDiv = document.getElementById(«test»);
var demoDiv = document.getElementById(«demo»);
demoDiv.innerHTML = «offsetLeft: » + testDiv.offsetLeft + «
offsetTop: » + testDiv.offsetTop;
Пример
Создайте липкую панель навигации:
//Получить панель навигации
var navbar = document.getElementById(«navbar»);
// Получить смещенное положение навигационной панели
var sticky = navbar.offsetTop;
// Добавьте класс sticky на панель навигации, когда достигнете ее положения прокрутки. Повторно используйте класс sticky, когда вы покидаете положение прокрутки.
function myFunction() if (window.pageYOffset >= sticky) navbar.classList.add(«sticky»)
> else navbar.classList.remove(«sticky»);
>
>