Wykrywanie, kiedy użytkownik przewija do dołu div za pomocą jQuery

219

Mam pole div (zwane flux) ze zmienną ilością treści w środku. W tym polu divbox ustawiono przepełnienie na automatyczne.

Teraz próbuję zrobić, gdy przewiń za pomocą przewiń na dół tego DIV-box, załaduj więcej treści na stronę, wiem jak to zrobić (załadować zawartość), ale nie wiem jak to zrobić wykryć, kiedy użytkownik przewinął do dołu tagu div? Gdybym chciał to zrobić dla całej strony, wziąłbym .scrollTop i odjąć to od .height.

Ale nie mogę tego tutaj zrobić?

Próbowałem pobrać .scrollTop z strumienia, a następnie zawinąć całą zawartość w div nazywany wewnętrznym, ale jeśli wezmę innerHeight strumienia, zwraca 564px (div jest ustawiony na 500 jako wysokość) i wysokość „wewnętrznego” zwraca 1064, a scrolltop, gdy na dole div mówi 564.

Co mogę zrobić?

Eax
źródło

Odpowiedzi:

422

Istnieje kilka właściwości / metod, których możesz użyć:

$().scrollTop()//how much has been scrolled
$().innerHeight()// inner height of the element
DOMElement.scrollHeight//height of the content of the element

Możesz więc wziąć sumę dwóch pierwszych właściwości, a gdy jest ona równa ostatniej właściwości, osiągnąłeś koniec:

jQuery(function($) {
    $('#flux').on('scroll', function() {
        if($(this).scrollTop() + $(this).innerHeight() >= $(this)[0].scrollHeight) {
            alert('end reached');
        }
    })
});

http://jsfiddle.net/doktormolle/w7X9N/

Edycja: Zaktualizowałem „wiązanie” do „wł.” Zgodnie z:

Począwszy od jQuery 1.7, metoda .on () jest preferowaną metodą dołączania procedur obsługi zdarzeń do dokumentu.

Dr.Molle
źródło
2
Wykona to wiązanie, gdy DOM będzie gotowy, aby upewnić się, że element # flux jest już dostępny.
Dr.Molle
1
powinieneś zaktualizować swoją odpowiedź używając ON zamiast
bindowania
34
Uwaga: gdy użytkownik korzysta z poziomów powiększenia w przeglądarce, może to nie działać. Zoom powoduje innerHeight()zgłaszanie miejsc po przecinku. W przypadku pomniejszenia użytkownika suma scrollTop()i innerHeight()zawsze będzie przynajmniej o ułamek sekundy mniejsza scrollHeight. Skończyło się na dodaniu strefy buforowej o wielkości 20 pikseli. Otrzymany uzależniona była if(el.scrollTop() + el.innerHeight() >= el[0].scrollHeight - 20)gdzie elrówna $(this).
Nick
1
To najlepsza odpowiedź, jaka kiedykolwiek działała dla mnie bardzo dobrze. Dzięki
Ashish Yadav,
1
Już nie działa, czy możesz potwierdzić, że to nie działa, dziękuję
Umair Shah Yousafzai
50

Znalazłem rozwiązanie, które po przewinięciu okna i wyświetleniu od dołu końca div wyświetla ostrzeżenie.

$(window).bind('scroll', function() {
    if($(window).scrollTop() >= $('.posts').offset().top + $('.posts').outerHeight() - window.innerHeight) {
        alert('end reached');
    }
});

W tym przykładzie przewinięcie w dół po .postszakończeniu funkcji div ( ) spowoduje wyświetlenie ostrzeżenia.

ehsan Aghaei
źródło
dziękuję za to, ale jak mogę ożywić div, gdy osiągnie dno tego div? również po przewinięciu w górę wykryj górę tego div, a następnie animuj również. Tak jak tutaj na tej stronie lazada.com.ph/apple zachowanie paska bocznego Mam nadzieję, że możesz mi pomóc :)
Alyssa Reyes
Działa to jak magia, ale problem polega na tym, że alert jest wykonywany dwa razy, więc jeśli masz wywołanie funkcji, zostanie on wykonany dwa razy
Afaf
1
@ 1616 Mam wcześniej var running = falsezadeklarowaną zmienną . Wewnątrz warunkowego sprawdzam W if(!running) { running = true; // and continue logic } ten sposób jest on wywoływany tylko raz! Po zakończeniu AJAX ustawrunning = false;
Jacob Raccuia
1
Chodzi o okno, ale pytanie dotyczy div.
Alexander Volkov
42

Chociaż pytanie zostało zadane 5,5 lat temu, nadal jest bardziej niż aktualne w kontekście dzisiejszego interfejsu użytkownika / interfejsu użytkownika. I chciałbym dodać moje dwa centy.

var element = document.getElementById('flux');
if (element.scrollHeight - element.scrollTop === element.clientHeight)
    {
        // element is at the end of its scroll, load more content
    }

Źródło: https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollHeight#Determine_if_an_element_has_been_totally_scrolled

Niektóre elementy nie pozwalają na przewijanie pełnej wysokości elementu. W takich przypadkach możesz użyć:

var element = docuement.getElementById('flux');
if (element.offsetHeight + element.scrollTop === element.scrollHeight) {
  // element is at the end of its scroll, load more content
}
Myślący
źródło
2
Jest to rozwiązanie, którego szukasz, jeśli nie używasz jQuery.
Petter Pettersson
Istnieje moduł obsługi zdarzeń?
Alexander Volkov
@AlexanderVolkov onscroll to powiązane wydarzenie.
Myślenie
9

Tylko dodatkowa uwaga tutaj, gdy znalazłem to, gdy szukam rozwiązania stałego diva, który chcę przewijać. W moim scenariuszu uznałem, że lepiej jest wziąć pod uwagę wypełnienie na div, aby móc dokładnie trafić do końca. Rozwijając odpowiedź @ Dr.Molle, dodaję:

$('#flux').bind('scroll', function() {
    var scrollPosition = $(this).scrollTop() + $(this).outerHeight();
    var divTotalHeight = $(this)[0].scrollHeight 
                          + parseInt($(this).css('padding-top'), 10) 
                          + parseInt($(this).css('padding-bottom'), 10)
                          + parseInt($(this).css('border-top-width'), 10)
                          + parseInt($(this).css('border-bottom-width'), 10);

    if( scrollPosition == divTotalHeight )
    {
      alert('end reached');
    }
  });

To da ci dokładną lokalizację, w tym wypełnienie i obramowania

Alexander Millar
źródło
7

To zadziałało dla mnie

$(window).scroll(function() {
  if ($(window).scrollTop() >= (($(document).height() - $(window).height()) - $('#divID').innerHeight())) {
    console.log('div reached');
  }
});
Ricardo Rivas
źródło
3

Jeśli potrzebujesz tego użyć na div, który ma przepełnienie-y jako ukryty lub przewijany, coś takiego może być tym, czego potrzebujesz.

if ($('#element').prop('scrollHeight') - $('#element').scrollTop() <= Math.ceil($('#element').height())) {
    at_bottom = true;
}

Odkryłem, że pułap jest potrzebny, ponieważ zwój rekwizytu wydaje się zaokrąglać, a może z innego powodu powoduje to wyłączenie o mniej niż 1.

Gęś
źródło
3

Jeśli nie używasz funkcji Math.round (), rozwiązanie sugerowane przez Dr.Molle nie będzie działać w niektórych przypadkach, gdy okno przeglądarki ma powiększenie.

Na przykład $ (this) .scrollTop () + $ (this) .innerHeight () = 600

$ (this) [0] .scrollHeight zwraca = 599,99998

600> = 599,99998 kończy się niepowodzeniem.

Oto poprawny kod:

jQuery(function($) {
    $('#flux').on('scroll', function() {
        if(Math.round($(this).scrollTop() + $(this).innerHeight(), 10) >= Math.round($(this)[0].scrollHeight, 10)) {
            alert('end reached');
        }
    })
});

Możesz także dodać dodatkowe piksele marginesów, jeśli nie potrzebujesz ścisłego warunku

var margin = 4

jQuery(function($) {
    $('#flux').on('scroll', function() {
        if(Math.round($(this).scrollTop() + $(this).innerHeight(), 10) >= Math.round($(this)[0].scrollHeight, 10) - margin) {
            alert('end reached');
        }
    })
});
Павел Гавриленко
źródło
2

W prostym użyciu DOM możesz sprawdzić warunek

element.scrollTop + element.clientHeight == element.scrollHeight

jeśli to prawda, osiągnąłeś koniec.

Louay Alosh
źródło
1

Jeśli ktoś dostaje scrollHeightjako undefined, a następnie wybierz 1st podelement elementów:mob_top_menu[0].scrollHeight

Starwave
źródło
1

nie jestem pewien, czy to jakaś pomoc, ale tak to robię.

Mam panel indeksu, który jest większy niż okno, i pozwalam mu się przewijać aż do końca tego indeksu. Potem naprawiam to na miejscu. Proces jest odwracany po przewinięciu w górę strony.

Pozdrowienia.

<style type="text/css">
    .fixed_Bot {    
            position: fixed;     
            bottom: 24px;    
        }     
</style>

<script type="text/javascript">
    $(document).ready(function () {
        var sidebarheight = $('#index').height();
        var windowheight = $(window).height();


        $(window).scroll(function () {
            var scrollTop = $(window).scrollTop();

            if (scrollTop >= sidebarheight - windowheight){
                $('#index').addClass('fixed_Bot');
            }
            else {
                $('#index').removeClass('fixed_Bot');
            }                   
        });
    });

</script>
Israel Chapa
źródło
1

Chociaż zadawano to prawie 6 lat temu, wciąż gorący temat w projektowaniu UX, oto fragment demonstracyjny, jeśli jakiś początkujący chciałby użyć

$(function() {

  /* this is only for demonstration purpose */
  var t = $('.posts').html(),
    c = 1,
    scroll_enabled = true;

  function load_ajax() {

    /* call ajax here... on success enable scroll  */
    $('.posts').append('<h4>' + (++c) + ' </h4>' + t);

    /*again enable loading on scroll... */
    scroll_enabled = true;

  }


  $(window).bind('scroll', function() {
    if (scroll_enabled) {

      /* if 90% scrolled */
    if($(window).scrollTop() >= ($('.posts').offset().top + $('.posts').outerHeight()-window.innerHeight)*0.9) {

        /* load ajax content */
        scroll_enabled = false;  
        load_ajax();
      }

    }

  });

});
h4 {
  color: red;
  font-size: 36px;
  background-color: yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<div class="posts">
  Lorem ipsum dolor sit amet  Consectetuer augue nibh lacus at <br> Pretium Donec felis dolor penatibus <br> Phasellus consequat Vivamus dui lacinia <br> Ornare nonummy laoreet lacus Donec <br> Ut ut libero Curabitur id <br> Dui pretium hendrerit
  sapien Pellentesque <br> Lorem ipsum dolor sit amet <br> Consectetuer augue nibh lacus at <br> Pretium Donec felis dolor penatibus <br> Phasellus consequat Vivamus dui lacinia <br> Ornare nonummy laoreet lacus Donec <br> Ut ut libero Curabitur id <br>  Dui pretium hendrerit sapien Pellentesque <br> Lorem ipsum dolor sit amet <br> Consectetuer augue nibh lacus at <br> Pretium Donec felis dolor penatibus <br> Phasellus consequat Vivamus dui lacinia <br> Ornare nonummy laoreet lacus Donec <br> Ut ut
  libero Curabitur id <br> Dui pretium hendrerit sapien Pellentesque <br> Lorem ipsum dolor sit amet <br> Consectetuer augue nibh lacus at <br> Pretium Donec felis dolor penatibus <br> Phasellus consequat Vivamus dui lacinia <br> Ornare nonummy laoreet
  lacus Donec <br> Ut ut libero Curabitur id <br> Dui pretium hendrerit sapien Pellentesque
</div>

Akshay Hegde
źródło
0

To jest rozwiązanie problemu z powiększeniem, działa na wszystkich poziomach powiększenia, w razie potrzeby:

if ( Math.abs(elem.offset().top) + elem.height() + elem.offset().top >= elem.outerHeight() ) {
                    console.log("bottom");
                    // We're at the bottom!
                }
            });
        }
Liad Livnat
źródło
0
$(window).on("scroll", function() {
    //get height of the (browser) window aka viewport
    var scrollHeight = $(document).height();
    // get height of the document 
    var scrollPosition = $(window).height() + $(window).scrollTop();
    if ((scrollHeight - scrollPosition) / scrollHeight === 0) {
        // code to run when scroll to bottom of the page
    }
});

To jest kod na github.

aki_sud
źródło
-1

Oto kolejna wersja.

Kluczowym kodem jest funkcja scroller (), która pobiera dane wejściowe jako wysokość div zawierającej przewijaną sekcję, używając funkcji przepełnienia: przewijania. Przybliża 5 pikseli od góry lub 10 pikseli od dołu, jak u góry lub u dołu. W przeciwnym razie jest zbyt wrażliwy. Wygląda na to, że 10 pikseli to minimum. Zobaczysz, że dodaje 10 do wysokości div, aby uzyskać dolną wysokość. Zakładam, że 5px może działać, nie testowałem zbytnio. YMMV. scrollHeight zwraca wysokość wewnętrznego obszaru przewijania, a nie wyświetlaną wysokość div, która w tym przypadku wynosi 400 pikseli.

<?php

$scrolling_area_height=400;
echo '
<script type="text/javascript">
          function scroller(ourheight) {
            var ourtop=document.getElementById(\'scrolling_area\').scrollTop;
            if (ourtop > (ourheight-\''.($scrolling_area_height+10).'\')) {
                alert(\'at the bottom; ourtop:\'+ourtop+\' ourheight:\'+ourheight);
            }
            if (ourtop <= (5)) {
                alert(\'Reached the top\');
            }
          }
</script>

<style type="text/css">
.scroller { 
            display:block;
            float:left;
            top:10px;
            left:10px;
            height:'.$scrolling_area_height.';
            border:1px solid red;
            width:200px;
            overflow:scroll; 
        }
</style>

$content="your content here";

<div id="scrolling_area" class="scroller">
onscroll="var ourheight=document.getElementById(\'scrolling_area\').scrollHeight;
        scroller(ourheight);"
        >'.$content.'
</div>';

?>
John Ostrowick
źródło
1
-1, ponieważ generowanie kodu javascript + css z php to zła praktyka (trudna w utrzymaniu, brak możliwości ponownego użycia, brak optymalizacji strony internetowej itp.). Ponadto, jak wskazał @Alexander Millar, przesunięcie 10px można naprawić, biorąc pod uwagę wypełnianie. Każdy, kto rozważa użycie tego kodu, powinien pomyśleć dwa razy ...
Kapitein Witbaard,