Как получить положение полосы прокрутки с помощью Javascript?

191

Я пытаюсь определить положение полосы прокрутки браузера с помощью JavaScript, чтобы решить, где на странице находится текущее представление. Я предполагаю, что мне нужно определить, где находится большой палец на дорожке, а затем высоту большого пальца в процентах от общей высоты дорожки. Я слишком усложняю это, или JavaScript предлагает более простое решение, чем это? Есть идеи по коду?

Павел
источник

Ответы:

210

Вы можете использовать element.scrollTopи, element.scrollLeftчтобы получить вертикальное и горизонтальное смещение, соответственно, которое было прокручено. elementможет быть, document.bodyесли вы заботитесь о всей странице. Вы можете сравнить его element.offsetHeightи element.offsetWidth(опять же, elementможет быть тело), ​​если вам нужны проценты.

Макс Шавабке
источник
2
Какой браузер вы используете? Получение тела выполняется по-разному в разных браузерах ( elementи document.bodyбыли только примерами). Подробности смотрите в howtocreate.co.uk/tutorials/javascript/browserwindow .
Макс Шавабке
8
Я получил его, чтобы дать мне правильное значение в Firefox 3.6 с window.pageYOffset, но не могу заставить что-либо работать на IE7. Пробовал window.pageYOffset, document.body.scrollTop, document.documentElement.scrollTop,element.scrollTop
Paul
1
scrollTop работал только для меня, когда я добавил скобки ... $ (". scrollBody"). scrollTop ()
май
9
Если вы имеете дело с элементом 'window', вы можете использовать window.scrollY вместо window.scrollTop
Янис Янсен
6
Я думаю, что позиция прокрутки не установлена document.bodyв большинстве современных браузеров - обычно она установлена document.documentElementсейчас. См. Bugs.chromium.org/p/chromium/issues/detail?id=157855 для перехода Chrome.
fzzfzzfzz
134

Я сделал это для <div>Chrome.

Элемент .scrollTop - это пиксели, скрытые в верхней части из-за прокрутки. Без прокрутки его значение равно 0.

Элемент .scrollHeight - это пиксели всего деления.

Элемент .clientHeight - это пиксели, которые вы видите в своем браузере.

var a = element.scrollTop;

будет позиция.

var b = element.scrollHeight - element.clientHeight;

будет максимальным значением для scrollTop .

var c = a / b;

будет процент прокрутки [от 0 до 1] .

Гэтсби
источник
3
Это почти правильно. для var b вы должны вычитать window.innerHeight, а не element.clientHeight.
Kahless
51
document.getScroll = function() {
    if (window.pageYOffset != undefined) {
        return [pageXOffset, pageYOffset];
    } else {
        var sx, sy, d = document,
            r = d.documentElement,
            b = d.body;
        sx = r.scrollLeft || b.scrollLeft || 0;
        sy = r.scrollTop || b.scrollTop || 0;
        return [sx, sy];
    }
}

возвращает массив с двумя целыми числами - [scrollLeft, scrollTop]

Kennebec
источник
4
Показывать, как использовать эту функцию на примере, было бы здорово.
user18490
1
Я думаю, вы можете использовать это lastscroll = getScroll (); window.scrollTo (lastscroll [0], lastscroll [1]);
Динеш Раджан
Работает отлично, но я изменил возврат к объекту с ключами x и y, так как это имеет немного больше смысла для меня.
xd6_
Отредактировано после комментария @ user18490.
Давиде Канниццо
ReferenceError: Невозможно найти переменную: element
Джонни
33

это вот так :)

window.addEventListener("scroll", function (event) {
    var scroll = this.scrollY;
    console.log(scroll)
});
Брайан Пастор
источник
12

Ответ на 2018 :

Лучший способ сделать это - использовать API Intersection Observer .

API Intersection Observer предоставляет способ асинхронно наблюдать изменения в пересечении целевого элемента с элементом-предком или с областью просмотра документа верхнего уровня.

Исторически, обнаружение видимости элемента или относительной видимости двух элементов по отношению друг к другу было трудной задачей, решения которой были ненадежными и склонными к тому, что браузер и сайты, к которым пользователь обращается, стали вялыми. К сожалению, по мере взросления сети потребность в такой информации возросла. Информация о пересечении необходима по многим причинам, таким как:

  • Ленивая загрузка изображений или другого контента при прокрутке страницы.
  • Реализация веб-сайтов с «бесконечной прокруткой», где все больше и больше контента загружается и отображается при прокрутке, чтобы пользователю не приходилось пролистывать страницы.
  • Отчет о видимости рекламы с целью расчета доходов от рекламы.
  • Решение о том, выполнять или нет задачи или процессы анимации, в зависимости от того, увидит ли пользователь результат.

Реализация обнаружения пересечений в прошлом включала в себя обработчики событий и циклы, вызывающие методы, такие как Element.getBoundingClientRect (), для создания необходимой информации для каждого затронутого элемента. Поскольку весь этот код выполняется в основном потоке, даже один из них может вызвать проблемы с производительностью. Когда сайт загружается с этими тестами, все может стать ужасно.

Смотрите следующий пример кода:

var options = {
  root: document.querySelector('#scrollArea'),
  rootMargin: '0px',
  threshold: 1.0
}

var observer = new IntersectionObserver(callback, options);

var target = document.querySelector('#listItem');
observer.observe(target);

Большинство современных браузеров поддерживают IntersectionObserver , но вы должны использовать polyfill для обратной совместимости.

ул
источник
8

если вы заботитесь о всей странице. Вы можете использовать это:

document.body.getBoundingClientRect().top

lemospy
источник
1
вместо этого используйте document.body
Дэниел Дезфули
3

Если вы используете jQuery, то для вас есть идеальная функция: .scrollTop ()

документ здесь -> http://api.jquery.com/scrollTop/

примечание: вы можете использовать эту функцию, чтобы получить ИЛИ установить положение.

см. также: http://api.jquery.com/?s=scroll

Симон Лосось
источник
25
Зачем отвечать на вопрос о JS с библиотекой для JS, когда это вполне возможно и даже удобно делать в сыром JS? Вы просто просите его добавить дополнительное время загрузки, а также использовать некоторое пространство для чего-то совершенно ненужного. Кроме того, с каких пор javascript стал означать JQuery?
DaemonOfTheWest
4
если вы спрашиваете индивидуально, мне никогда не нравился jQuery, и я не отвечал на этот вопрос, но в Vanilla JS уже есть ответы, данные другими участниками, тогда в чем проблема, если кто-то добавил вкусную специю в эту ветку (он уже упоминал, что если вы используете jQuery)
Ravinder Payal
@ R01010010 потому что в наши дни JQuery бесполезен и контрпродуктивен, все функции из JQuery легко реализуются с помощью VanilaJS, также вы становитесь зависимыми от того, что находится внутри JQuery, с новыми функциями, доступными в VanillsaJS, вы, как программист, не будете обновлять, просто как пример В настоящее время в VanillaJS появился новый API под названием fetch, который заменил старый XHR, если вы только что оказались в мире JQuery, вы никогда не увидите преимуществ при получении и продолжите использовать jQuery.ajax (). Мое личное мнение таково, что люди, которые продолжают с помощью JQuery это потому, что они перестали учиться. Также VanillaJS быстрее vanilla-js.com
Джон Балвин Ариас
@JohnBalvinArias говорит о получении, что случилось на ie11 или даже Edge?
Бен
Поправьте меня, если я ошибаюсь, но fetch не работает должным образом на "modern", т. Е. И т. Е. Все еще широко используется. Если бы я использовал jquery, меня вряд ли бы поощрили двигаться дальше
Бен
3

Вот другой способ получить позицию прокрутки

const getScrollPosition = (el = window) => ({
  x: el.pageXOffset !== undefined ? el.pageXOffset : el.scrollLeft,
  y: el.pageYOffset !== undefined ? el.pageYOffset : el.scrollTop
});
Gor
источник
0

Я думаю, что следующая функция может помочь получить значения координат прокрутки:

const getScrollCoordinate = (el = window) => ({
  x: el.pageXOffset || el.scrollLeft,
  y: el.pageYOffset || el.scrollTop,
});

Я получил эту идею из этого ответа с небольшим изменением.

AmerllicA
источник