Erkennen, wann der Benutzer mit jQuery zum Ende von div blättert

218

Ich habe eine Div-Box (genannt Flux) mit einer variablen Menge an Inhalten. Bei dieser Divbox ist der Überlauf auf Auto eingestellt.

Was ich jetzt versuche, ist, wenn die Verwendung zum Ende dieser DIV-Box scrollen, mehr Inhalt in die Seite laden, weiß ich, wie das geht (lade den Inhalt), aber ich weiß nicht, wie Erkennen, wann der Benutzer zum Ende des div-Tags gescrollt hat? Wenn ich es für die gesamte Seite tun wollte, würde ich .scrollTop nehmen und das von .height subtrahieren.

Aber ich kann das hier nicht tun?

Ich habe versucht, .scrollTop aus dem Fluss zu nehmen und dann den gesamten Inhalt in ein Div mit dem Namen inner zu verpacken. Wenn ich jedoch die innere Höhe des Flusses nehme, werden 564px (das div ist auf 500 als Höhe festgelegt) und die Höhe von 'innner' zurückgegeben. es gibt 1064 zurück und das Scrolltop, wenn am unteren Rand des Div 564 steht.

Was kann ich tun?

Eax
quelle

Antworten:

420

Es gibt einige Eigenschaften / Methoden, die Sie verwenden können:

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

Sie können also die Summe der ersten beiden Eigenschaften nehmen, und wenn sie der letzten Eigenschaft entspricht, haben Sie das Ende erreicht:

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

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

Bearbeiten: Ich habe 'bind' auf 'on' aktualisiert wie folgt:

Ab jQuery 1.7 ist die Methode .on () die bevorzugte Methode zum Anhängen von Ereignishandlern an ein Dokument.

Dr.Molle
quelle
2
Die Bindung wird ausgeführt, wenn das DOM bereit ist, um sicherzustellen, dass das Flussmittelelement # bereits verfügbar ist.
Dr.Molle
1
Sie sollten
Ihre
34
Hinweis: Wenn ein Benutzer Zoomstufen in seinem Browser verwendet, funktioniert dies möglicherweise nicht. Durch das Zoomen werden innerHeight()Dezimalstellen gemeldet. Wenn ein Benutzer herauszoomt, ist die Summe von scrollTop()und innerHeight()immer mindestens ein Bruchteil von scrollHeight. Am Ende habe ich eine Pufferzone von 20px hinzugefügt. Die resultierende Bedingung war, if(el.scrollTop() + el.innerHeight() >= el[0].scrollHeight - 20)wo elgleich ist $(this).
Nick
1
Dies ist die beste Antwort, die jemals für mich sehr gut funktioniert hat. Vielen Dank
Ashish Yadav
1
Es funktioniert nicht mehr. Können Sie bitte bestätigen, warum es nicht funktioniert
Umair Shah Yousafzai
50

Ich habe eine Lösung gefunden, die Sie beim Scrollen Ihres Fensters und am Ende eines von unten angezeigten Divs alarmiert.

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

Wenn Sie in diesem Beispiel nach unten scrollen, wenn div ( .posts) fertig ist, erhalten Sie eine Warnung.

ehsan Aghaei
quelle
Danke dafür, aber wie kann ich das Div animieren, wenn es den Boden dieses Div erreicht? Auch wenn Sie nach oben scrollen, erkennen Sie die Oberseite dieses Divs und animieren Sie dann ebenfalls. Genau wie hier auf dieser Website lazada.com.ph/apple das Seitenleistenverhalten Hoffe, Sie können mir helfen :)
Alyssa Reyes
Es funktioniert wie eine Magie, aber das Problem ist, dass die Warnung zweimal ausgeführt wird. Wenn Sie also eine Funktion aufrufen, wird sie zweimal ausgeführt
Afaf
1
@ 1616 Ich habe vorher eine Variable var running = falsedeklariert. Innerhalb der Bedingung überprüfe ich Auf if(!running) { running = true; // and continue logic } diese Weise wird es nur einmal aufgerufen! Wenn der AJAX abgeschlossen ist, setzen Sierunning = false;
Jacob Raccuia
1
Es geht um Fenster, aber bei der Frage geht es um Div.
Alexander Volkov
42

Obwohl die Frage vor 5,5 Jahren gestellt wurde, ist sie im heutigen UI / UX-Kontext mehr als relevant. Und ich möchte meine zwei Cent hinzufügen.

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

Quelle: https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollHeight#Determine_if_an_element_has_been_totally_scrolled

Bei einigen Elementen können Sie nicht über die gesamte Höhe des Elements scrollen. In diesen Fällen können Sie verwenden:

var element = docuement.getElementById('flux');
if (element.offsetHeight + element.scrollTop === element.scrollHeight) {
  // element is at the end of its scroll, load more content
}
Denken
quelle
2
Dies ist die Lösung, nach der Sie suchen, wenn Sie jQuery nicht verwenden.
Petter Pettersson
Gibt es den Event-Handler?
Alexander Volkov
@AlexanderVolkov onscroll ist das verwandte Ereignis.
Denken
9

Nur eine zusätzliche Anmerkung hier, da ich diese gefunden habe, als ich nach einer Lösung für ein festes Div gesucht habe, das ich scrollen möchte. Für mein Szenario habe ich festgestellt, dass es vorzuziehen ist, die Polsterung auf dem Div zu berücksichtigen, damit ich das Ende genau treffen kann. Um die Antwort von @ Dr.Molle zu erweitern, füge ich Folgendes hinzu

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

Das gibt Ihnen den genauen Ort, einschließlich Polsterung und Ränder

Alexander Millar
quelle
7

das hat aber bei mir funktioniert

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

Wenn Sie dies für ein Div verwenden müssen, dessen Überlauf als ausgeblendet oder gescrollt ist, ist möglicherweise Folgendes erforderlich.

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

Ich fand, dass Ceil benötigt wurde, weil Prop ScrollHeight zu runden scheint, oder vielleicht aus einem anderen Grund, der dazu führt, dass dies um weniger als 1 abweicht.

Gans
quelle
3

Wenn Sie die Funktion Math.round () nicht verwenden, funktioniert die von Dr.Molle vorgeschlagene Lösung in einigen Fällen nicht, wenn ein Browserfenster über einen Zoom verfügt.

Zum Beispiel $ (this) .scrollTop () + $ (this) .innerHeight () = 600

$ (this) [0] .scrollHeight ergibt = 599.99998

600> = 599.99998 schlägt fehl.

Hier ist der richtige Code:

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

Sie können auch einige zusätzliche Randpixel hinzufügen, wenn Sie keine strenge Bedingung benötigen

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');
        }
    })
});
Павел Гавриленко
quelle
2

In der einfachen DOM-Verwendung können Sie den Zustand überprüfen

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

Wenn ja, dann haben Sie das Ende erreicht.

Louay Alosh
quelle
1

Wenn jemand scrollHeightals bekommt undefined, wählen Sie das erste Unterelement der Elemente aus:mob_top_menu[0].scrollHeight

Starwave
quelle
1

Ich bin mir nicht sicher, ob es Hilfe ist, aber so mache ich es.

Ich habe ein Indexfenster, das größer als das Fenster ist, und ich lasse es scrollen, bis das Ende dieses Index erreicht ist. Dann fixiere ich es in Position. Der Vorgang wird umgekehrt, sobald Sie zum oberen Rand der Seite scrollen.

Grüße.

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

Obwohl dies vor fast 6 Jahren gefragt wurde, vor immer noch heißes Thema im UX-Design, hier ist ein Demo-Snippet, wenn ein Neuling verwenden wollte

$(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
quelle
0

Leute, dies ist die Lösung für das Zoom-Problem. Es funktioniert mit allen Zoomstufen, falls Sie es brauchen:

if ( Math.abs(elem.offset().top) + elem.height() + elem.offset().top >= elem.outerHeight() ) {
                    console.log("bottom");
                    // We're at the bottom!
                }
            });
        }
Liad Livnat
quelle
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
    }
});

Dies ist der Code auf Github.

aki_sud
quelle
-1

Hier ist eine andere Version.

Der Schlüsselcode ist function scroller (), der die Eingabe als Höhe des Divs mit dem Bildlaufabschnitt unter Verwendung von overflow: scroll verwendet. Es beträgt ungefähr 5 Pixel von oben oder 10 Pixel von unten wie oben oder unten. Sonst ist es zu empfindlich. Es scheint, dass 10px ungefähr das Minimum ist. Sie werden sehen, dass die Div-Höhe um 10 erhöht wird, um die untere Höhe zu erhalten. Ich gehe davon aus, dass 5px funktionieren könnte, ich habe nicht ausgiebig getestet. YMMV. scrollHeight gibt die Höhe des inneren Bildlaufbereichs zurück, nicht die angezeigte Höhe des div, die in diesem Fall 400 Pixel beträgt.

<?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
quelle
1
-1, weil das Generieren von Javascript + CSS-Code aus PHP eine schlechte Praxis ist (schwer zu warten, keine Wiederverwendbarkeit, keine Website-Optimierungen usw.). Wie von @Alexander Millar hervorgehoben, kann der 10px-Offset durch Berücksichtigung der Polsterung korrigiert werden. Jeder, der erwägt, diesen Code zu verwenden, sollte zweimal
überlegen