Rilevamento quando l'utente scorre fino alla fine del div con jQuery


226

Ho una casella div (chiamata flusso) con una quantità variabile di contenuto all'interno. Questo divbox ha l'overflow impostato su automatico.

Ora, quello che sto cercando di fare è, quando l'uso scorre fino alla fine di questo DIV-box, carica più contenuti nella pagina, so come farlo (carica il contenuto) ma non so come rilevare quando l'utente è passato alla fine del tag div? Se volessi farlo per l'intera pagina, prenderei .scrollTop e lo sottraerei da .height.

Ma non riesco a farlo qui?

Ho provato a prendere .scrollTop da flux, quindi avvolgere tutto il contenuto all'interno di un div chiamato inner, ma se prendo innerHeight di flux restituisce 564px (il div è impostato su 500 come altezza) e l'altezza di 'innner' restituisce 1064 e lo scrolltop, quando in fondo al div dice 564.

Cosa posso fare?

Risposte:


436

Ci sono alcune proprietà / metodi che puoi usare:

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

Quindi puoi prendere la somma delle prime due proprietà e, quando è uguale all'ultima proprietà, hai raggiunto la fine:

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

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

Modifica: ho aggiornato "bind" a "on" secondo:

A partire da jQuery 1.7, il metodo .on () è il metodo preferito per allegare gestori di eventi a un documento.


2
Eseguirà il binding quando il DOM sarà pronto per essere sicuro che l'elemento # flux sia già disponibile.
Dottor Molle

1
dovresti aggiornare la tua risposta usando ON invece di bind, bind è deprecato a favore di On
ncubica

38
Nota: quando un utente utilizza i livelli di zoom sul proprio browser, potrebbe non funzionare. Lo zoom fa innerHeight()riportare i decimali. Nel caso di un utente che rimpicciolisce, la somma di scrollTop()e innerHeight()sarà sempre almeno una frazione inferiore a scrollHeight. Ho finito per aggiungere una zona cuscinetto di 20px. Il condizionale risultante era if(el.scrollTop() + el.innerHeight() >= el[0].scrollHeight - 20)dove è eluguale $(this).
Nick

1
Questa è la migliore risposta in assoluto che ha funzionato molto bene per me. Grazie
Ashish Yadav

1
Non funziona più, puoi confermare il motivo per cui non funziona, grazie
Umair Shah Yousafzai

53

Ho trovato una soluzione che quando scorri la finestra e alla fine di un div mostrato dal basso ti dà un avviso.

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

In questo esempio, se scorri verso il basso quando div ( .posts) finisce ti darà un avviso.


grazie per questo ma come posso animare il div quando raggiunge il fondo di quel div? anche quando scorri verso l'alto rileva la parte superiore di quel div quindi anima anche. Proprio come qui su questo sito web lazada.com.ph/apple il comportamento della barra laterale Spero che tu possa aiutarmi :)
Alyssa Reyes

Funziona come una magia ma il problema è che l'avviso viene eseguito due volte, quindi se hai una chiamata di una funzione al suo interno verrà eseguita due volte
Afaf

1
@ 1616 Ho una variabile var running = falsedichiarata prima di questa. All'interno del condizionale, controllo In if(!running) { running = true; // and continue logic } questo modo viene chiamato solo una volta! Quando l'AJAX sarà completo, impostarerunning = false;
Jacob Raccuia

2
Riguarda la finestra, ma la domanda riguarda div.
Alexander Volkov

44

Sebbene la domanda sia stata posta 5,5 anni fa, è ancora più che pertinente nel contesto dell'interfaccia utente / UX di oggi. E vorrei aggiungere i miei due centesimi.

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

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

Alcuni elementi non ti permetteranno di scorrere l'intera altezza dell'elemento. In questi casi puoi usare:

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

3
Questa è la soluzione che stai cercando se non stai usando jQuery.
Petter Pettersson

1
C'è il gestore di eventi?
Alexander Volkov

1
@AlexanderVolkov onscroll è l'evento correlato.
Pensando il

10

Solo una nota aggiuntiva qui perché l'ho trovata quando cercavo una soluzione per un div fisso che voglio scorrere. Per il mio scenario ho scoperto che è preferibile tenere conto del padding sul div in modo da poter raggiungere la fine esattamente. Quindi, espandendo la risposta di @ Dr.Molle aggiungo quanto segue

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

Questo ti darà la posizione precisa, inclusi padding e bordi


7

questo ha funzionato per me però

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

3

Se devi usarlo su un div che ha overflow-y come nascosto o scroll, qualcosa del genere potrebbe essere ciò di cui hai bisogno.

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

Ho scoperto che ceil era necessario perché prop scrollHeight sembra arrotondato, o forse qualche altro motivo per cui questo è meno di 1.


3

Se non stai usando la funzione Math.round () la soluzione suggerita da Dr.Molle non funzionerà in alcuni casi quando una finestra del browser ha uno zoom.

Ad esempio $ (this) .scrollTop () + $ (this) .innerHeight () = 600

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

600> = 599.99998 non riesce.

Ecco il codice corretto:

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

Puoi anche aggiungere alcuni pixel di margine extra se non hai bisogno di una condizione rigorosa

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

3

In un semplice utilizzo del DOM puoi controllare la condizione

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

se è vero, sei arrivato alla fine.


1

Se qualcuno ottiene scrollHeightcome undefined, seleziona il primo sottoelemento degli elementi:mob_top_menu[0].scrollHeight


1

non sono sicuro che sia d'aiuto, ma è così che lo faccio.

Ho un pannello indice più grande della finestra e lo lascio scorrere fino alla fine di questo indice. Quindi lo aggiusto in posizione. Il processo viene invertito una volta che si scorre verso la parte superiore della pagina.

Saluti.

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

1

Anche se questo è stato chiesto quasi 6 anni fa, un argomento ancora caldo nel design UX, ecco uno snippet demo se qualche principiante voleva usarlo

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


0

Ecco un'altra versione.

Il codice del tasto è funzione scroller () che prende l'input come l'altezza del div contenente la sezione di scorrimento, usando overflow: scroll. Si avvicina a 5px dall'alto o 10px dal basso come in alto o in basso. Altrimenti è troppo sensibile. Sembra che 10px sia il minimo. Vedrai che aggiunge 10 all'altezza del div per ottenere l'altezza inferiore. Presumo che 5px potrebbe funzionare, non ho testato ampiamente. YMMV. scrollHeight restituisce l'altezza dell'area di scorrimento interna, non l'altezza visualizzata del div, che in questo caso è 400px.

<?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>';

?>

1
-1 perché generare codice javascript + css da php è una cattiva pratica (difficile da mantenere, nessuna riutilizzabilità, nessuna ottimizzazione del sito web, ecc.) Inoltre, come sottolineato da @Alexander Millar, l'offset di 10px può essere corretto tenendo conto del padding. Chiunque
stia

0

Ragazzi questa è la soluzione al problema dello zoom, funziona con tutti i livelli di zoom, nel caso ne abbiate bisogno:

if ( Math.abs(elem.offset().top) + elem.height() + elem.offset().top >= elem.outerHeight() ) {
                    console.log("bottom");
                    // We're at the bottom!
                }
            });
        }

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

Questo è il codice su GitHub.


0

Ho creato questo pezzo di codice che ha funzionato per me per rilevare quando scorro fino alla fine di un elemento!

let element = $('.element');

if ($(document).scrollTop() > element.offset().top + element.height()) {

     /// do something ///
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.