Разница между window.pageYOffset и document.body.getBoundingClientRect (). Top?

Я делаю индикатор выполнения в зависимости от того, сколько прокручиваете. Какой из этих двух мне следует использовать?

function getScrollValue() {
    return ((parseInt(document.body.getBoundingClientRect().top) * -1));
}

или

function getScrollValue() {
    return window.pageYOffset;
}
IntersectionObserver, вероятно, лучшее решение для этого.
str 27.12.2018 15:56

Используйте window.pageYOffset (IntersectionObserver не поддерживается IE)

Jakob E 27.12.2018 15:59

@JakobE Есть полифил.

str 27.12.2018 16:01

Да, но в этом случае (просто отслеживание прокрутки страницы) это излишне (полифилл также использует прослушиватели прокрутки). Я бы использовал прослушиватели прокрутки и пассивные события, если они доступны

Jakob E 27.12.2018 16:09

@JakobE IntersectionObserver существует потому, что наивное решение для обработчиков прокрутки часто создает проблемы с производительностью. Повышение производительности для совместимых браузеров при одновременном предоставлении полифилла для сильно устаревших браузеров - не излишество.

str 27.12.2018 16:12

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

Jakob E 27.12.2018 16:18

Позвольте нам продолжить обсуждение в чате.

Jakob E 27.12.2018 16:21
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
7
631
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Помимо того, что window.pageYOffset является более специализированным API, а также более производительным решением для определения значения прокрутки, использование getBoundingClientRect().top для попытки сделать то же самое может иметь неожиданные результаты, если, например, у тела есть некоторый верхний край, который смещает его положение.

РЕДАКТИРОВАТЬ

Я включил следующий jsPerf Test, который показывает существенную разницу в производительности между двумя альтернативами, а также то, как работает третий (более старый) API по сравнению с ними.

Простой пример с использованием тега индикатора выполнения

/* test if passive events are supported */
var supportsPassive = false;
try { var opts = Object.defineProperty({}, 'passive', { get: function() { supportsPassive = true; }});
  window.addEventListener("testPassive", null, opts);
  window.removeEventListener("testPassive", null, opts);
} catch (e) {}

/* progress element */
const progress = document.querySelector('progress');

/* scroll listener */
addEventListener('scroll', e => {
    progress.value = pageYOffset/(document.body.clientHeight - innerHeight);
}, supportsPassive ? { passive: true } : false);
/* stretch and fix progress */ 
progress { width: 100%; position: fixed; }

/* add some scroll to the page */
body { margin: 0; height: 20000px; }
<progress value = "0"></progress>

Другие вопросы по теме