JavaScript getBoundingClientRect() изменяется при прокрутке
Я хочу иметь точное расстояние между Y-координатой элемента и значением Y = 0, которое я рассматриваю как верхнюю часть документа.
myElement.getBoundingClientRect().top;
Но значение getBoundingClientRect(), похоже, изменяется при прокрутке. Как я могу получить реальное расстояние между myElement и Y-координатой = 0 (верхняя часть документа)?
Ответы
Ответ 1
Это потому, что getBoundingClientRect()
получает значения по отношению к window
(только текущая видимая часть страницы), а не document
(целая страница).
Следовательно, он также учитывает прокрутку при расчете его значений
В принципе, document = window + scroll
Итак, чтобы получить расстояние между myElement и Y-координатой = 0 (верхняя часть документа), вы также добавили бы значение вертикальной прокрутки:
myElement.getBoundingClientRect().top + window.scrollY;
Источник: https://developer.mozilla.org/en-US/docs/Web/API/Element.getBoundingClientRect
Ответ 2
getBoundingClientRect требует немного больше внимания, чтобы избежать ошибок в scrollY/pageYOffset:
function absolutePosition(el) {
var
found,
left = 0,
top = 0,
width = 0,
height = 0,
offsetBase = absolutePosition.offsetBase;
if (!offsetBase && document.body) {
offsetBase = absolutePosition.offsetBase = document.createElement('div');
offsetBase.style.cssText = 'position:absolute;left:0;top:0';
document.body.appendChild(offsetBase);
}
if (el && el.ownerDocument === document && 'getBoundingClientRect' in el && offsetBase) {
var boundingRect = el.getBoundingClientRect();
var baseRect = offsetBase.getBoundingClientRect();
found = true;
left = boundingRect.left - baseRect.left;
top = boundingRect.top - baseRect.top;
width = boundingRect.right - boundingRect.left;
height = boundingRect.bottom - boundingRect.top;
}
return {
found: found,
left: left,
top: top,
width: width,
height: height,
right: left + width,
bottom: top + height
};
}
Ошибки, которых следует избегать:
-
прокрутка в Android Chrome, так как Chrome Mobile 43 имеет неправильные значения для scrollY/pageYOffset (особенно когда клавиатура отображается и вы прокручиваете).
-
Пинч-зум в Microsoft IE или Edge вызывает неправильные значения для scrollY/pageYOffset.
-
Некоторые (устаревшие) браузеры не имеют высоты/ширины, например. IE8
Изменить: приведенный выше код можно упростить, просто используя document.body.getBoundingClientRect()
вместо добавления div - я его не пробовал, поэтому оставляю свой ответ в его нынешнем виде. Также тело нуждается в margin:0
(reset.css обычно делает это). Этот ответ значительно упрощает код, сохраняя при этом ошибки в jQuery.offset()!