Проверьте, прокрутил ли пользователь до дна - PullRequest
613 голосов
/ 10 октября 2010

Я делаю систему нумерации страниц (вроде как Facebook), где контент загружается, когда пользователь прокручивает страницу до конца.Я полагаю, что лучший способ сделать это - найти пользователя внизу страницы и выполнить ajax-запрос для загрузки большего количества сообщений.

Единственная проблема - я не знаю, как проверить,пользователь прокрутил страницу вниз с помощью jQuery.Есть идеи?

Мне нужно найти способ проверить, когда пользователь прокрутил страницу вниз с помощью jQuery.

Ответы [ 22 ]

949 голосов
/ 10 октября 2010

Используйте событие .scroll() для window, например:

$(window).scroll(function() {
   if($(window).scrollTop() + $(window).height() == $(document).height()) {
       alert("bottom!");
   }
});

Вы можете проверить это здесь , это занимает верхнюю прокрутку окна, поэтому, насколько оно прокручивается вниз, добавляет высоту видимого окна и проверяет, равна ли это высоте всего содержимого ( document). Если вы хотите вместо этого проверить, находится ли пользователь около снизу, это выглядело бы примерно так:

$(window).scroll(function() {
   if($(window).scrollTop() + $(window).height() > $(document).height() - 100) {
       alert("near bottom!");
   }
});

Вы можете протестировать эту версию здесь , просто настройте 100 на любой пиксель снизу, который вы хотите активировать.

112 голосов
/ 29 мая 2012

Ответ Ника Крейвера работает отлично, за исключением проблемы, связанная с тем, что значение $(document).height() зависит от браузера.

Чтобы оно работало во всех браузерах, используйте эту функцию из Джеймс Падолси :

function getDocHeight() {
    var D = document;
    return Math.max(
        D.body.scrollHeight, D.documentElement.scrollHeight,
        D.body.offsetHeight, D.documentElement.offsetHeight,
        D.body.clientHeight, D.documentElement.clientHeight
    );
}

вместо $(document).height(), поэтому конечный код:

$(window).scroll(function() {
       if($(window).scrollTop() + $(window).height() == getDocHeight()) {
           alert("bottom!");
       }
   });
84 голосов
/ 31 декабря 2015

Я не совсем уверен, почему это еще не было опубликовано, но согласно документации MDN , самый простой способ - использовать нативные свойства javascript:

element.scrollHeight - element.scrollTop === element.clientHeight

Возвращает true, когда вы находитесь внизу любого прокручиваемого элемента.Так что просто с помощью javascript:

element.addEventListener('scroll', function(event)
{
    var element = event.target;
    if (element.scrollHeight - element.scrollTop === element.clientHeight)
    {
        console.log('scrolled');
    }
});

scrollHeight имеют широкую поддержку в браузерах, то есть от 8, если быть более точным, тогда как clientHeight и scrollTop поддерживаются всеми.Даже то есть 6. Это должно быть кросс-браузерным.

47 голосов
/ 01 октября 2012

Для тех, кто использует решение Ника и получает повторные оповещения / срабатывание событий, вы можете добавить строку кода над примером оповещения:

$(window).scroll(function() {
   if($(window).scrollTop() + $(window).height() > $(document).height() - 100) {
       $(window).unbind('scroll');
       alert("near bottom!");
   }
});

Это означает, что код будет срабатывать только в первый раз, когда вы окажетесь в пределах 100 пикселей от нижней части документа. Это не повторится, если вы прокрутите назад вверх, а затем назад вниз, что может или не может быть полезным в зависимости от того, для чего вы используете код Ника.

39 голосов
/ 13 марта 2013

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

var _throttleTimer = null;
var _throttleDelay = 100;
var $window = $(window);
var $document = $(document);

$document.ready(function () {

    $window
        .off('scroll', ScrollHandler)
        .on('scroll', ScrollHandler);

});

function ScrollHandler(e) {
    //throttle event:
    clearTimeout(_throttleTimer);
    _throttleTimer = setTimeout(function () {
        console.log('scroll');

        //do work
        if ($window.scrollTop() + $window.height() > $document.height() - 100) {
            alert("near bottom!");
        }

    }, _throttleDelay);
}
37 голосов
/ 03 июля 2013

Ответ Ника Крейвера должен быть слегка изменен для работы на iOS 6 Safari Mobile и должен быть:

$(window).scroll(function() {
   if($(window).scrollTop() + window.innerHeight == $(document).height()) {
       alert("bottom!");
   }
});

Изменение $ (окно) .height () на window.innerHeight должно быть сделано, потому что когда адресная строка скрыта дополнительные 60 пикселей добавляются к высоте окна, но использование $(window).height() не не отражает это изменение, а использование window.innerHeight делает.

Примечание : свойство window.innerHeight также включает в себя высоту горизонтальной полосы прокрутки (если она отображается), в отличие от $(window).height(), которая не будет включать высоту горизонтальной полосы прокрутки. Это не проблема в Mobile Safari, но может вызвать непредвиденное поведение в других браузерах или будущих версиях Mobile Safari. Изменение == на >= может исправить это в большинстве случаев использования.

Подробнее о window.innerHeight недвижимости здесь

19 голосов
/ 09 марта 2016

Вот довольно простой подход:

elm.onscroll = function() {
    if(elm.scrollTop + elm.clientHeight == elm.scrollHeight) //User has scrolled to the bottom of the element
}
15 голосов
/ 19 февраля 2014

Вот фрагмент кода, который поможет вам отладить ваш код. Я проверил приведенные выше ответы и обнаружил, что они содержат ошибки.Я протестировал следующее на Chrome, IE, Firefox, IPad (Safari).У меня нет других установленных для тестирования ...

<script type="text/javascript">
   $(function() {
      $(window).scroll(function () {
         var docElement = $(document)[0].documentElement;
         var winElement = $(window)[0];

         if ((docElement.scrollHeight - winElement.innerHeight) == winElement.pageYOffset) {
            alert('bottom');
         }
      });
   });
</script>

Возможно, есть более простое решение, но я остановился на том моменте, когда ЭТО РАБОТАЛО

Если у вас все еще есть проблемы с каким-то мошенническим браузером, вот код, который поможет вам отладить:

<script type="text/javascript">
   $(function() {
      $(window).scroll(function () {
         var docElement = $(document)[0].documentElement;
         var details = "";
         details += '<b>Document</b><br />';
         details += 'clientHeight:' + docElement.clientHeight + '<br />';
         details += 'clientTop:' + docElement.clientTop + '<br />';
         details += 'offsetHeight:' + docElement.offsetHeight + '<br />';
         details += 'offsetParent:' + (docElement.offsetParent == null) + '<br />';
         details += 'scrollHeight:' + docElement.scrollHeight + '<br />';
         details += 'scrollTop:' + docElement.scrollTop + '<br />';

         var winElement = $(window)[0];
         details += '<b>Window</b><br />';
         details += 'innerHeight:' + winElement.innerHeight + '<br />';
         details += 'outerHeight:' + winElement.outerHeight + '<br />';
         details += 'pageYOffset:' + winElement.pageYOffset + '<br />';
         details += 'screenTop:' + winElement.screenTop + '<br />';
         details += 'screenY:' + winElement.screenY + '<br />';
         details += 'scrollY:' + winElement.scrollY + '<br />';

         details += '<b>End of page</b><br />';
         details += 'Test:' + (docElement.scrollHeight - winElement.innerHeight) + '=' + winElement.pageYOffset + '<br />';
         details += 'End of Page? ';
         if ((docElement.scrollHeight - winElement.innerHeight) == winElement.pageYOffset) {
             details += 'YES';
         } else {
             details += 'NO';
         }

         $('#test').html(details);
      });
   });
</script>
<div id="test" style="position: fixed; left:0; top: 0; z-index: 9999; background-color: #FFFFFF;">

Надеюсь, это сэкономит кому-то время.

11 голосов
/ 25 ноября 2015

Это мои два цента:

$('#container_element').scroll( function(){
        console.log($(this).scrollTop()+' + '+ $(this).height()+' = '+ ($(this).scrollTop() + $(this).height())   +' _ '+ $(this)[0].scrollHeight  );
        if($(this).scrollTop() + $(this).height() == $(this)[0].scrollHeight){
            console.log('bottom found');
        }
    });
11 голосов
/ 13 ноября 2016
var elemScrolPosition = elem.scrollHeight - elem.scrollTop - elem.clientHeight;

Рассчитывает полосу прокрутки расстояния до нижней части элемента.Равен 0, если полоса прокрутки достигла дна.

...