it-swarm.dev

Sprawdź, czy użytkownik przewinął się na sam dół

Robię system stronicowania (coś w rodzaju Facebooka), gdzie zawartość ładuje się, gdy użytkownik przewinie się na dół. Wyobrażam sobie, że najlepszym sposobem na to jest znalezienie, kiedy użytkownik znajduje się u dołu strony i uruchomienie zapytania ajax, aby załadować więcej postów.

Jedyny problem polega na tym, że nie wiem, jak sprawdzić, czy użytkownik przewinął do dołu strony za pomocą jQuery. Jakieś pomysły?

Muszę znaleźć sposób, aby sprawdzić, kiedy użytkownik przewinął się na dół strony za pomocą jQuery.

583
Johnny

Użyj zdarzenia .scroll() na window, tak jak poniżej:

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

Możesz to przetestować tutaj , to zajmuje górny zwój okna, więc ile przewinięto w dół, dodaje wysokość widocznego okna i sprawdza, czy to równa wysokości całej treści (document). Jeśli zamiast tego chcesz sprawdzić, czy użytkownik ma wartość near, wyglądałby mniej więcej tak:

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

Możesz przetestować tę wersję tutaj , po prostu dostosuj 100 do dowolnego piksela od dołu, na którym chcesz wywołać.

925
Nick Craver

Odpowiedź Nicka Cravera działa dobrze, oszczędza się kwestii, że wartość $(document).height() zależy od przeglądarki.

Aby działał we wszystkich przeglądarkach, użyj tej funkcji z 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
    );
}

w miejsce $(document).height(), tak aby ostateczny kod:

$(window).scroll(function() {
       if($(window).scrollTop() + $(window).height() == getDocHeight()) {
           alert("bottom!");
       }
   });
107
Miles O'Keefe

Nie jestem do końca pewien, dlaczego nie zostało to jeszcze opublikowane, ale zgodnie z dokumentacją z MDN , najprostszym sposobem jest użycie natywnych właściwości javascript:

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

Zwraca wartość true, gdy znajdujesz się u dołu dowolnego przewijanego elementu. Po prostu używając javascript:

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

scrollHeight ma szerokie wsparcie w przeglądarkach, od 8 do dokładniejszych, a clientHeight i scrollTop są obsługiwane przez wszystkich. Nawet np. 6. To powinno być bezpieczne w przeglądarkach.

67

Dla osób korzystających z rozwiązania Nicka i powtarzających się ostrzeżeń/zdarzeń, możesz dodać linię kodu powyżej przykładu alertu:

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

Oznacza to, że kod zostanie uruchomiony dopiero po pierwszym osiągnięciu 100px dolnej części dokumentu. Nie powtórzy się, jeśli przewiniesz kopię zapasową, a następnie z powrotem, co może, ale nie musi być przydatne w zależności od tego, do czego używasz kodu Nicka.

46
Tim Carr

Oprócz znakomitej, zaakceptowanej odpowiedzi od Nicka Cravera, można zdławić zdarzenie przewijania tak, aby nie było tak często wystrzeliwane, a więc zwiększanie wydajności przeglądarki :

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

Odpowiedź Nicka Cravera musi zostać nieco zmieniona, aby działała na iOS 6 Safari Mobile i powinna być:

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

Zmiana $ (window) .height () na window.innerHeight powinna być wykonana, ponieważ gdy pasek adresu jest ukryty, dodatkowe 60px jest dodawane do Wysokość okna, ale użycie $(window).height() powoduje, że not odzwierciedla tę zmianę, podczas gdy używa się window.innerHeight.

Note: Właściwość window.innerHeight zawiera także wysokość poziomego paska przewijania (jeśli jest renderowana), w odróżnieniu od $(window).height(), która nie będzie zawierać wysokości poziomego paska przewijania. Nie stanowi to problemu w Safari mobilnym, ale może spowodować nieoczekiwane zachowanie w innych przeglądarkach lub przyszłych wersjach Mobile Safari. Zmiana == na >= może rozwiązać ten problem w większości typowych przypadków użycia.

Przeczytaj więcej o właściwości window.innerHeighttutaj

36
Yosi

Oto dość proste podejście:

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

Oto fragment kodu, który pomoże ci zdebugować twój kod, przetestowałem powyższe odpowiedzi i stwierdziłem, że są błędne. Testowałem następujące rzeczy w Chrome, IE, Firefox, IPad (Safari). Nie mam żadnych innych zainstalowanych do przetestowania ...

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

Może być prostsze rozwiązanie, ale zatrzymałem się w punkcie, w którym IT WORKED

Jeśli nadal masz problemy z jakąś nieuczciwą przeglądarką, oto kod pomagający w debugowaniu:

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

Mam nadzieję, że to uratuje kogoś kiedyś.

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

Oblicza pasek przewijania odległości na spód elementu ........ Równy 0, jeśli pasek przewijania został osiągnięty na dole. 

10
Vasyl Gutnyk

Sprawdź tę odpowiedź

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

Możesz zrobić footerHeight - document.body.offsetHeight, aby zobaczyć, czy jesteś blisko stopki, czy dotarł do stopki

10
Junaid Qadir

To są moje dwa centy:

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

Czysty JS z w różnych przeglądarkach i ogłaszanie (Całkiem dobra wydajność )

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

Demo: http://jsbin.com/geherovena/edit?js,output

PS: Debouncer, getScrollXY, getDocHeight nie napisane przeze mnie

Po prostu pokazuję, jak to działa i jak to zrobię

5
l2aelba

Możesz wypróbować poniższy kod,

$("#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');
    }
});
3
Shahrukh Anwar

Nick odpowiada, że ​​będzie dobrze, ale będziesz miał funkcje, które powtarza się podczas przewijania lub nie będzie działać, jeśli użytkownik ma powiększone okno. Wpadłem na łatwą poprawkę, po prostu math.round na pierwszej wysokości i działa tak, jak zakładałem.

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

Wypróbuj to dla warunku dopasowania, jeśli przewiń do dolnego końca

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

    //code for your custom logic

}
2
Hiren Patel

Wszystkie te rozwiązania nie działają dla mnie w Firefoksie i Chrome, więc używam niestandardowych funkcji z Miles O'Keefe i meder omuraliev like this:

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

Pozwól mi pokazać approch bez JQuery. Prosta funkcja 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;
}

Krótki przykład jak z niego korzystać:

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

Daje to dokładne wyniki podczas sprawdzania przewijanego elementu element (tzn. Nie window):

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

offsetHeight powinien nadać rzeczywisty widoczny wysokość elementu (włączając dopełnienie, margines, i scrollbars), a scrollHeight to whole height elementu zawierającego niewidoczne (przepełnione) obszary.

jQuery.outerHeight() powinno dać podobny rezultat do JS .offsetHeight -- Dokumentacja w MDN dla offsetHeight jest niejasna co do obsługi wielu przeglądarek. Aby objąć więcej opcji, jest to bardziej kompletne:

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

0
Yuval A.

Aby zatrzymać powtarzanie ostrzeżenia o odpowiedzi Nicka

ScrollActivate();

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

Google Chrome podaje pełną wysokość strony, jeśli zadzwonisz $(window).height()

Zamiast tego użyj window.innerHeight, aby pobrać wysokość okna. Niezbędne sprawdzenie powinno być:

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

Użyłem @ddanone answear i dodałem połączenie 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();
    }
}

}

0
Henrique C.

Moje rozwiązanie w prostym js:

let el=document.getElementById('el');
el.addEventListener('scroll', function (e) {
		if (el.scrollHeight - el.scrollTop - el.clientHeight<0) {
      console.log('Bottom')
    }
});
#el{
  width:300px;
  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>

0
Bakos Bence

Oto moje dwa centy, ponieważ zaakceptowana odpowiedź nie zadziałała.

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