Проверьте, прокручивается ли пользователь на дно

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

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

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

Ответ 1

Используйте .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 на любой пиксель снизу, на который вы хотите включить.

Ответ 2

Ответ Nick Craver отлично работает, избавляет от проблемы, что значение $(document).height() зависит от браузера.

Чтобы он работал на всех браузерах, используйте эту функцию из James Padolsey:

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!");
       }
   });

Ответ 3

Я не совсем уверен, почему это еще не опубликовано, но согласно документации из 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. Это должно быть безопасным для браузера.

Ответ 4

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

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

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

Ответ 5

В дополнение к превосходному принятому ответу от Nick Craver вы можете дросселировать событие прокрутки так, чтобы оно не запускалось так часто, таким образом увеличение производительности браузера:

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);
}

Ответ 6

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

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

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

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

Подробнее о свойстве window.innerHeight здесь

Ответ 7

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

elm.onscroll = function() {
    if(elm.scrollTop + elm.clientHeight == elm.scrollHeight) //User has scrolled to the bottom of the element
}

Ответ 8

Вот фрагмент кода, который поможет вам отладить ваш код, я протестировал вышеупомянутые ответы и обнаружил, что они ошибочны. Я тестировал следующие действия в 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>

Может быть более простое решение, но я остановился в точке, где IT WORKED

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

<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;">

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

Ответ 9

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

$('#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');
        }
    });

Ответ 10

var elemScrolPosition = elem.scrollHeight - elem.scrollTop - elem.clientHeight;

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

Ответ 11

Пожалуйста, проверьте этот ответ

 window.onscroll = function(ev) {
    if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight) {
       console.log("bottom");
    }
};

Вы можете сделать footerHeight - document.body.offsetHeight, чтобы увидеть, находитесь ли вы рядом с нижним колонтитулом или достигли нижнего колонтитула

Ответ 12

Pure JS с кросс-браузер и debouncing (довольно хорошая производительность)

var CheckIfScrollBottom = debouncer(function() {
    if(getDocHeight() == getScrollXY()[1] + window.innerHeight) {
       console.log('Bottom!');
    }
},500);

document.addEventListener('scroll',CheckIfScrollBottom);

function debouncer(a,b,c){var d;return function(){var e=this,f=arguments,g=function(){d=null,c||a.apply(e,f)},h=c&&!d;clearTimeout(d),d=setTimeout(g,b),h&&a.apply(e,f)}}
function getScrollXY(){var a=0,b=0;return"number"==typeof window.pageYOffset?(b=window.pageYOffset,a=window.pageXOffset):document.body&&(document.body.scrollLeft||document.body.scrollTop)?(b=document.body.scrollTop,a=document.body.scrollLeft):document.documentElement&&(document.documentElement.scrollLeft||document.documentElement.scrollTop)&&(b=document.documentElement.scrollTop,a=document.documentElement.scrollLeft),[a,b]}
function getDocHeight(){var a=document;return Math.max(a.body.scrollHeight,a.documentElement.scrollHeight,a.body.offsetHeight,a.documentElement.offsetHeight,a.body.clientHeight,a.documentElement.clientHeight)}

Демо: http://jsbin.com/geherovena/edit?js,output

PS: Debouncer, getScrollXY, getDocHeight не написано мной

Я просто покажу, как его работа, И как я буду делать

Ответ 13

Nick отвечает на все вопросы, но у вас будут функции, которые повторяются при прокрутке или вообще не будут работать, если пользователь увеличил окно. Я придумал простое исправление только математике. Вокруг первой высоты и работает так же, как предполагалось.

    if (Math.round($(window).scrollTop()) + $(window).innerHeight() == $(document).height()){
    loadPagination();
    $(".go-up").css("display","block").show("slow");
}

Ответ 14

Вы можете попробовать следующий код,

$("#dashboard-scroll").scroll(function(){
    var ele = document.getElementById('dashboard-scroll');
    if(ele.scrollHeight - ele.scrollTop === ele.clientHeight){
       console.log('at the bottom of the scroll');
    }
});

Ответ 15

Мое решение в простой JS:

let el=document.getElementById('el');
el.addEventListener('scroll', function(e) {
    if (this.scrollHeight - this.scrollTop - this.clientHeight<=0) {
        alert('Bottom');
    }
});
#el{
  width:400px;
  height:100px;
  overflow-y:scroll;
}
<div id="el">
<div>content</div>
<div>content</div>
<div>content</div>
<div>content</div>
<div>content</div>
<div>content</div>
<div>content</div>
<div>content</div>
<div>content</div>
<div>content</div>
<div>content</div>
</div>

Ответ 16

Попробуйте это для условия соответствия, если прокрутить до нижнего конца

if ($(this)[0].scrollHeight - $(this).scrollTop() == 
    $(this).outerHeight()) {

    //code for your custom logic

}

Ответ 17

Все эти решения не работают для меня в Firefox и Chrome, поэтому я использую пользовательские функции из Miles O'Keefe и meder omuraliev вот так:

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
    );
}

function getWindowSize()
{
  var myWidth = 0, myHeight = 0;
  if( typeof( window.innerWidth ) == 'number' ) {
    //Non-IE
    myWidth = window.innerWidth;
    myHeight = window.innerHeight;
  } else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
    //IE 6+ in 'standards compliant mode'
    myWidth = document.documentElement.clientWidth;
    myHeight = document.documentElement.clientHeight;
  } else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
    //IE 4 compatible
    myWidth = document.body.clientWidth;
    myHeight = document.body.clientHeight;
  }
  return [myWidth, myHeight];
}

$(window).scroll(function()
{
    if($(window).scrollTop() + getWindowSize()[1] == getDocHeight())
    {
        alert("bottom!");
    }
});

Ответ 18

Это дает точные результаты при проверке прокручиваемого элемента (т.е. не window):

// 'element' is a native JS HTMLElement
if ( element.scrollTop == (element.scrollHeight - element.offsetHeight) )
    // Element scrolled to bottom

offsetHeight должен давать фактическую видимую высоту элемента (включая отступы, поля и полосы прокрутки), а scrollHeight - всю высоту элемента, включая невидимые (переполненные) области.

jQuery .outerHeight() должен давать аналогичный результат для JS .offsetHeight - документация в MDN для offsetHeight неясно о его кросс-браузерной поддержке. Чтобы охватить больше вариантов, это более полно:

var offsetHeight = ( container.offsetHeight ? container.offsetHeight : $(container).outerHeight() );
if  ( container.scrollTop == (container.scrollHeight - offsetHeight) ) {
   // scrolled to bottom
}

Ответ 19

Позвольте мне показать соответствие без JQuery. Простая функция JS:

function isVisible(elem) {
  var coords = elem.getBoundingClientRect();
  var topVisible = coords.top > 0 && coords.top < 0;
  var bottomVisible = coords.bottom < shift && coords.bottom > 0;
  return topVisible || bottomVisible;
}

Короткий пример того, как его использовать:

var img = document.getElementById("pic1");
    if (isVisible(img)) { img.style.opacity = "1.00";  }

Ответ 20

Я использовал @ddonone answear и добавил вызов Ajax.

$('#mydiv').on('scroll', function(){
  function infiniScroll(this);
});

function infiniScroll(mydiv){
console.log($(mydiv).scrollTop()+' + '+ $(mydiv).height()+' = '+ ($(mydiv).scrollTop() + $(mydiv).height())   +' _ '+ $(mydiv)[0].scrollHeight  );

if($(mydiv).scrollTop() + $(mydiv).height() == $(mydiv)[0].scrollHeight){
    console.log('bottom found');
    if(!$.active){ //if there is no ajax call active ( last ajax call waiting for results ) do again my ajax call
        myAjaxCall();
    }
}

}

Ответ 21

Чтобы остановить повторное оповещение о ответе Ника.

ScrollActivate();

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

Ответ 22

Google Chrome дает полную высоту страницы, если вы звоните $(window).height()

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

if($(window).scrollTop() + window.innerHeight > $(document).height() - 50) {
    console.log("reached bottom!");
}

Ответ 23

Здесь мои два цента как принятый ответ не работали для меня.

var documentAtBottom = (document.documentElement.scrollTop + window.innerHeight) >= document.documentElement.scrollHeight;