Javascript: Как определить, прокручивается ли окно браузера вниз?


187

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

Как я могу определить, прокручивается ли пользователь внизу страницы или прокручивается ли он выше на странице?


1
Этот работает в Angular 6 -> stackoverflow.com/a/42547136/621951
Гюнай Гюльтекин

Ответы:


268
window.onscroll = function(ev) {
    if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight) {
        // you're at the bottom of the page
    }
};

Посмотреть демо


29
Не работает, когда элементы html / body установлены на 100% (так что тело заполняет всю высоту области просмотра)
Grodriguez

5
Используйте document.documentElement.scrollTopвместо window.scrollYIE. Не уверен, какие версии IE поддерживаются window.scrollY.
Батандва

3
Не работает в Chromium версии 47.0.2526.73 Построена на Ubuntu 14.04, работает на элементарной ОС 0.3.2 (64-битная)
K - Токсичность в SO растет.

9
Я использовал document.body.scrollHeight вместо offsetHeight (в моем случае offsetHeight всегда был меньше, чем window.innerHeight)
Оливер

1
@KarlMorrison Можете ли вы попробовать награду за вознаграждение (@Dekel) с вашим браузером?
Basj

115

Обновлен код для всех основных браузеров (включая IE10 и IE11)

window.onscroll = function(ev) {
    if ((window.innerHeight + window.pageYOffset) >= document.body.offsetHeight) {
        alert("you're at the bottom of the page");
    }
};

Проблема с текущим принятым ответом заключается в том, что window.scrollYон недоступен в IE.

Вот цитата из mdn относительно scrollY:

Для кросс-браузерной совместимости используйте window.pageYOffset вместо window.scrollY.

И рабочий фрагмент:

Примечание для Mac

Судя по комментарию @ Raphaël, в Mac возникла проблема из-за небольшого смещения.
Работает следующее обновленное условие:

(window.innerHeight + window.pageYOffset) >= document.body.offsetHeight - 2

У меня не было возможности проверить это дальше, если кто-то может прокомментировать эту конкретную проблему, это будет здорово.


Подтвердили работу на FF, Chrome, IE10, Chrome для Android. Спасибо @Dekel!
Basj

2
Как это ни странно звучит, только в моем браузере мне не хватает 1 пикселя, и, следовательно, условие не срабатывает. Не уверен, почему, пришлось добавить несколько дополнительных пикселей, чтобы это работало.
Шарджил Ахмед

3
на компьютерах Mac условие ниже не выполняется из-за небольшого смещения (~ 1 пикселя), мы обновили условие следующим образом(window.innerHeight + window.pageYOffset) >= document.body.offsetHeight - 2
Raphaël

4
спасибо @Dekel! на самом деле, мы обнаруживаем, что window.pageYOffset является плавающей точкой на Mac. Наше окончательное решение (window.innerHeight + Math.ceil(window.pageYOffset + 1)) >= document.body.offsetHeight.
Рафаэль

2
Не работает для случаев, когда тело имеет стиль, который устанавливает высоту на 100%
raRaRa

56

Принятый ответ не работал для меня. Это сделал:

window.onscroll = function(ev) {
    if ((window.innerHeight + window.scrollY) >= document.body.scrollHeight) {
      // you're at the bottom of the page
      console.log("Bottom of page");
    }
};

Если вы ищете поддержку старых браузеров (IE9), используйте псевдоним, window.pageYOffsetкоторый имеет немного лучшую поддержку.


1
не работает в IE10 / 11. Проверьте ответ Декеля ( stackoverflow.com/questions/9439725/… ) для поддержки IE. Работал для меня
Herr_Schwabullek

Другие ответы вызывали console.log () каждый раз, когда я прокручивал, а не только когда находился внизу страницы. Этот ответ работал для меня на Chrome.
Defcronyke

Если вы избавляетесь от window.scrollY, который не работает в ie или edge, это достойный ответ. Заменить на: (window.innerHeight + window.pageYOffset)> = document.body.scrollHeight
colemerrick

21

Я искал ответ, но не нашел точного. Вот чистое решение javascript, которое работает с последними версиями Firefox, IE и Chrome:

// document.body.scrollTop alone should do the job but that actually works only in case of Chrome.
// With IE and Firefox it also works sometimes (seemingly with very simple pages where you have
// only a <pre> or something like that) but I don't know when. This hack seems to work always.
var scrollTop = (document.documentElement && document.documentElement.scrollTop) || document.body.scrollTop;

// Grodriguez's fix for scrollHeight:
// accounting for cases where html/body are set to height:100%
var scrollHeight = (document.documentElement && document.documentElement.scrollHeight) || document.body.scrollHeight;

// >= is needed because if the horizontal scrollbar is visible then window.innerHeight includes
// it and in that case the left side of the equation is somewhat greater.
var scrolledToBottom = (scrollTop + window.innerHeight) >= scrollHeight;

// As a bonus: how to scroll to the bottom programmatically by keeping the horizontal scrollpos:
// Since window.innerHeight includes the height of the horizontal scrollbar when it is visible
// the correct vertical scrollTop would be
// scrollHeight-window.innerHeight+sizeof(horizontal_scrollbar)
// Since we don't know the visibility/size of the horizontal scrollbar
// we scroll to scrollHeight that exceeds the value of the
// desired scrollTop but it seems to scroll to the bottom with all browsers
// without problems even when the horizontal scrollbar is visible.
var scrollLeft = (document.documentElement && document.documentElement.scrollLeft) || document.body.scrollLeft;
window.scrollTo(scrollLeft, scrollHeight);

4
Это почти сработало для меня, но мне пришлось использовать ((document.documentElement && document.documentElement.scrollHeight) || document.body.scrollHeight)вместо того, document.body.scrollHeightчтобы просто учитывать случаи, когда html / body установлены на высоту: 100%
Grodriguez

1
@Grodriguez Спасибо за информацию! Это может пригодиться нам в будущем! :-)
pasztorpisti

15

Это работает

window.onscroll = function() {

    // @var int totalPageHeight
    var totalPageHeight = document.body.scrollHeight; 

    // @var int scrollPoint
    var scrollPoint = window.scrollY + window.innerHeight;

    // check if we hit the bottom of the page
    if(scrollPoint >= totalPageHeight)
    {
        console.log("at the bottom");
    }
}

Если вы ищете поддержку старых браузеров (IE9), замените window.scrollY на window.pageYOffset


1
эта работа с реагирует в 2019 году. работа с телом 100% роста, стоит с HTML 100% роста. работа с Chrome, Safari, Firefox, края.
сердитый киви

Просто примечание: необходимо изменить имя - переменные должны быть изменены. Потому что scrollHeight показывает общую высоту страницы, а totalHeight показывает текущую точку прокрутки, поэтому это немного сбивает с толку.
Владимир Мартон

4

Я только начал смотреть на это, и ответы здесь помогли мне, так что спасибо за это. Я немного расширил, чтобы код был безопасным вплоть до IE7:

Надеюсь, это окажется полезным для кого-то.

Здесь есть скрипка;)

    <!DOCTYPE html>
<html>
<head>
    <style>
        div {
            height: 100px;
            border-bottom: 1px solid #ddd;
        }

        div:nth-child(even) {
            background: #CCC
        }

        div:nth-child(odd) {
            background: #FFF
        }

    </style>
</head>

<body>
<div></div><div></div><div></div><div></div><div></div><div></div><div></div>
<div></div><div></div><div></div><div></div><div></div><div></div><div></div>
<div></div><div></div><div></div><div></div><div></div><div></div><div></div>
<div></div><div></div><div></div><div></div><div></div><div></div><div></div>
<div></div><div></div><div></div><div></div><div></div><div></div><div></div>
</body>

<script type="text/javascript">
console.log("Doc Height = " + document.body.offsetHeight);
console.log("win Height = " + document.documentElement.clientHeight);
window.onscroll = function (ev) {
    var docHeight = document.body.offsetHeight;
    docHeight = docHeight == undefined ? window.document.documentElement.scrollHeight : docHeight;

    var winheight = window.innerHeight;
    winheight = winheight == undefined ? document.documentElement.clientHeight : winheight;

    var scrollpoint = window.scrollY;
    scrollpoint = scrollpoint == undefined ? window.document.documentElement.scrollTop : scrollpoint;

    if ((scrollpoint + winheight) >= docHeight) {
        alert("you're at the bottom");
    }
};
</script>
</html>

Вроде работ. Но это не очень точно. Он считает, что он прокручивается до дна, пока вы находитесь в пределах 16 пикселей от дна.
Питер Холл

4

Если вы настраиваете height: 100%какой-либо контейнер <div id="wrapper">, то работает следующий код (проверено в Chrome):

var wrapper = document.getElementById('wrapper');

wrapper.onscroll = function (evt) {
  if (wrapper.scrollTop + window.innerHeight >= wrapper.scrollHeight) {
    console.log('reached bottom!');
  }
}

3
window.onscroll = function(ev) {
    if ((window.innerHeight + Math.ceil(window.pageYOffset)) >= document.body.offsetHeight) {
        alert("you're at the bottom of the page");
    }
};

Этот ответ зафиксирует крайние случаи, это происходит потому , что pageYOffsetэто в doubleто время , innerHeightи offsetHeightявляются long, поэтому , когда браузер дает вам информацию, вы можете быть пиксель коротким. Например: внизу страницы мы имеем

правда window.innerHeight = 10.2

правда window.pageYOffset = 5.4

правда document.body.offsetHeight = 15.6

Наш расчет тогда становится: 10 + 5.4> = 16, что неверно

Чтобы это исправить мы можем сделать Math.ceilпо pageYOffsetзначению.

Надеюсь, это поможет.



2

Вы можете заглянуть в бесконечный свиток jquery:

http://www.infinite-scroll.com/infinite-scroll-jquery-plugin/

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


2
Хотя эта ссылка может ответить на вопрос, лучше включить сюда основные части ответа и предоставить ссылку для справки. Ответы, содержащие только ссылки, могут стать недействительными, если связанная страница изменится.
bobthedeveloper

@Hatsjoem Он ссылается на плагин. Какие именно «основные части» следует скопировать? Кому интересно, если ответ «станет недействительным, если связанная страница изменится»? Если ссылка не работает, это означает, что плагин был прекращен и больше не существует - даже если вы добавите больше информации к ответу, он все равно будет недействительным. Боже, ответы только на ссылки не обязательно плохие.
dcastro

@Hatsjoem Кроме того, из мета : «Когда указанная библиотека находится в хорошо известном стабильном месте, этот тип ответа является, как правило, плохим ответом, но, тем не менее, ответом :« используйте это »».
dcastro

Кроме того, Google, вероятно, все еще будет существовать, если бесконечная прокрутка изменит этот URL. Смысл в том, чтобы использовать этот плагин, поэтому, если ссылка умирает, просто Google Search JQuery бесконечной прокрутки. Вы, вероятно, найдете то, что вам нужно.
Кай Цин

2

Удивительно, но ни одно из решений не сработало для меня. Я думаю, это потому, что мой cssбыл испорчен, и bodyне использовал весь контент при использовании height: 100%(пока не знаю, почему). Однако, ища решение, я придумал что-то хорошее ... в основном то же самое, но, возможно, стоит взглянуть - я новичок в программировании, так что извините, если он делает то же самое медленнее, менее поддерживается или что-то вроде который...

window.onscroll = function(evt) {
  var check = (Element.getBoundingClientRect().bottom - window.innerHeight <= 0) ? true : false;
  if (check) { console.log("You're at the bottom!"); }
};

2
$(document).ready(function(){
    $('.NameOfYourDiv').on('scroll',chk_scroll);
});

function chk_scroll(e)
{
    var elem = $(e.currentTarget);
    if (elem[0].scrollHeight - elem.scrollTop() == elem.outerHeight()) 
    {
        alert("scrolled to the bottom");
    }

}

ИДК другой точки зрения. Но принятый ответ лучше наверняка
Зихан Чжан

2
const handleScroll = () => {
    if (Math.round(window.scrollY + window.innerHeight) >= Math.round(document.body.scrollHeight)) {
        onScroll();
    }
};

Этот код работал для меня в Firefox и IE, а также.


1

Использование defaultViewи documentElementсо встроенным фрагментом функционального кода:

const { defaultView } = document;
const { documentElement } = document;
const handler = evt => requestAnimationFrame(() => {
  const hitBottom = (() => (defaultView.innerHeight + defaultView.pageYOffset) >= documentElement.offsetHeight)();
  hitBottom
    ? console.log('yep')
    : console.log('nope')
});
document.addEventListener('scroll', handler);
<pre style="height:110vh;background-color:fuchsia">scroll down</pre>


1

Вы можете проверить, является ли объединенный результат высоты окна и прокрутки больше, чем у тела

if (window.innerHeight + window.scrollY >= document.body.scrollHeight) {}


0

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

Следующий фрагмент кода управляет прокруткой вниз до нижней части страницы:

JavascriptExecutor js = (JavascriptExecutor) driver;
boolean found = false;
long currOffset = 0;
long oldOffset = 0;
do
{
    oldOffset = currOffset;
    // LOOP to seek the component using several xpath regexes removed
    js.executeScript("window.scrollBy(0, 100)");
    currOffset = (Long)js.executeScript("var offset = window.window.pageYOffset; return offset;");
} while (!found && (currOffset != oldOffset));

Кстати, окно развернуто до того, как этот фрагмент кода будет выполнен.


0

Принятый ответ не работал для меня. Это сделал:

const element = document.createElement('div');
document.body.appendChild(element);
document.addEventListener('scroll', () => {
    const viewportHeight = window.innerHeight;
    const distance = element.getBoundingClientRect().top;
    if (Math.floor(distance) <= viewportHeight) {
        console.log('yep')
    } else {
        console.log('nope')
    }
})

0

Я нашел два решения, которые сработали для меня:

  window.addEventListener('scroll', function(e) {
    if (
      window.innerHeight + document.documentElement.scrollTop ===
      document.documentElement.offsetHeight
    ) {
      console.log('You are at the bottom')
    }
  })

И другие:

  window.addEventListener('scroll', function(e) {
    if (
      window.innerHeight + window.pageYOffset ===
      document.documentElement.offsetHeight
    ) {
      console.log('You are at the bottom')
    }
  })
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.