jQuery carga más datos en scroll

148

Me pregunto cómo puedo implementar más datos en el desplazamiento solo si la carga div es visible.

Por lo general, buscamos la altura de la página y la altura de desplazamiento, para ver si necesitamos cargar más datos. pero el siguiente ejemplo es poco complicado entonces eso.

La siguiente imagen es un ejemplo perfecto. Hay dos div .loading en el cuadro desplegable. Cuando el usuario desplaza el contenido, lo que sea visible debe comenzar a cargar más datos para él.

ingrese la descripción de la imagen aquí

Entonces, ¿cómo puedo saber si .loading div es visible para el usuario o no? Entonces puedo comenzar a cargar datos solo para ese div.

Basit
fuente

Respuestas:

286

En jQuery, verifique si ha tocado el final de la página usando la función de desplazamiento. Una vez que presione eso, realice una llamada ajax (puede mostrar una imagen de carga aquí hasta la respuesta ajax) y obtenga el siguiente conjunto de datos, añádalo al div. Esta función se ejecuta cuando se desplaza hacia abajo de la página nuevamente.

$(window).scroll(function() {
    if($(window).scrollTop() == $(document).height() - $(window).height()) {
           // ajax call get data from server and append to the div
    }
});
deepakssn
fuente
55
Esta solución es excelente y la más simple;) Puede mejorar este código con las siguientes líneas en la llamada ajax: la new_element.hide().appendTo('.your_div').fadeIn(); $(window).scrollTop($(window).scrollTop()-1);primera línea agrega elementos de manera agradable, la segunda asegura que su función nunca se detiene en la parte inferior de la página.
alekwisnia
34
Abordo esto de manera similar, teniendo en cuenta el hecho de que siempre tiene cosas arbitrarias (navegación) en la parte inferior de su página, y realmente desea cargar antes de tocar la parte inferior. Entonces mi función interna es: var end = $("#BottomThing").offset().top; var viewEnd = $(window).scrollTop() + $(window).height(); var distance = end - viewEnd; if (distance < 300) // do load
Jeff Putz
2
Ryan Bates tiene un excelente episodio sobre esto: railscasts.com/episodes/114-endless-page . También hay una versión revisada, pero es posible que necesite una suscripción.
Vee
44
Si a alguien le gusta saber si un usuario se ha desplazado hacia abajo, puede usar esta condición if dentro del if que se muestra aquí: if ($ (window) .scrollTop () + $ (window) .height () == $ (document ) .height ()) {console.log ('¡Desplazado hacia abajo!'); }
Roy Shoa
55
Esta respuesta no es lo que he preguntado en la pregunta.
Basit
84

¿Has oído hablar del complemento jQuery Waypoint ?

A continuación se muestra la manera simple de llamar a un complemento de waypoints y hacer que la página cargue más contenido una vez que llegue al final del desplazamiento:

$(document).ready(function() {
    var $loading = $("<div class='loading'><p>Loading more items&hellip;</p></div>"),
    $footer = $('footer'),
    opts = {
        offset: '100%'
    };

    $footer.waypoint(function(event, direction) {
        $footer.waypoint('remove');
        $('body').append($loading);
        $.get($('.more a').attr('href'), function(data) {
            var $data = $(data);
            $('#container').append($data.find('.article'));
            $loading.detach();
            $('.more').replaceWith($data.find('.more'));
            $footer.waypoint(opts);
        });
    }, opts);
});
defau1t
fuente
8
alguna posibilidad de una demostración a través de jsfiddle?
cwiggo
44
buena sugerencia pero peor waypoint del complemento js ... perdí mucho tiempo ... la respuesta a continuación fue mucho más rápida
Karan Datwani
2
¿Qué respuesta a continuación te pareció la mejor?
wuno
Puede consultar mi respuesta para la implementación de Lazy Loader. stackoverflow.com/a/45846766/2702249
Om Sao
9

Aquí hay un ejemplo:

  1. Al desplazarse hacia abajo, se agregan elementos html. Este mecanismo de adición solo se realiza dos veces, y luego se agrega un botón con color azul polvo al final.

<!DOCTYPE html>
<html>
<head>
    <title>Demo: Lazy Loader</title>
    <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
    <style>
        #myScroll {
            border: 1px solid #999;
        }

        p {
            border: 1px solid #ccc;
            padding: 50px;
            text-align: center;
        }

        .loading {
            color: red;
        }
        .dynamic {
            background-color:#ccc;
            color:#000;
        }
    </style>
    <script>
		var counter=0;
        $(window).scroll(function () {
            if ($(window).scrollTop() == $(document).height() - $(window).height() && counter < 2) {
                appendData();
            }
        });
        function appendData() {
            var html = '';
            for (i = 0; i < 10; i++) {
                html += '<p class="dynamic">Dynamic Data :  This is test data.<br />Next line.</p>';
            }
            $('#myScroll').append(html);
			counter++;
			
			if(counter==2)
			$('#myScroll').append('<button id="uniqueButton" style="margin-left: 50%; background-color: powderblue;">Click</button><br /><br />');
        }
    </script>
</head>
<body>
    <div id="myScroll">
        <p>
            Contents will load here!!!.<br />
        </p>
        <p >This is test data.<br />Next line.</p>
        <p >This is test data.<br />Next line.</p>
        <p >This is test data.<br />Next line.</p>
        <p >This is test data.<br />Next line.</p>
        <p >This is test data.<br />Next line.</p>
        <p >This is test data.<br />Next line.</p>
        <p >This is test data.<br />Next line.</p>
        <p >This is test data.<br />Next line.</p>
        <p >This is test data.<br />Next line.</p>
        <p >This is test data.<br />Next line.</p>
        <p >This is test data.<br />Next line.</p>
        <p >This is test data.<br />Next line.</p>
        <p >This is test data.<br />Next line.</p>
        <p >This is test data.<br />Next line.</p>
        <p >This is test data.<br />Next line.</p>
        <p >This is test data.<br />Next line.</p>
        <p >This is test data.<br />Next line.</p>
        <p >This is test data.<br />Next line.</p>
        <p >This is test data.<br />Next line.</p>
        <p >This is test data.<br />Next line.</p>
        <p >This is test data.<br />Next line.</p>
        <p >This is test data.<br />Next line.</p>
    </div>
</body>
</html>

Om Sao
fuente
@RohanAshik: acabo de comprobarlo. Esta funcionando. Intenta desplazarte hacia abajo hasta el final.
Om Sao
@ Om Prakash Sao Funciona bien aquí, pero cuando ejecuto este código en sublime, el evento funciona cuando la barra de desplazamiento toca la parte superior, no la inferior, \
geek
8

La respuesta aceptada de esta pregunta tiene algún problema con Chrome cuando la ventana se acerca a un valor> 100%. Aquí está el código recomendado por los desarrolladores de Chrome como parte de un error que había generado en el mismo.

$(window).scroll(function() {
  if($(window).scrollTop() + $(window).height() >= $(document).height()){
     //Your code here
  }
});

Para referencia:

Pregunta SO relacionada

Error de Chrome

Prasanth KC
fuente
7

Si no todos sus documentos se desplazan, digamos, cuando tiene un desplazamiento divdentro del documento, entonces las soluciones anteriores no funcionarán sin adaptaciones. Aquí se explica cómo verificar si la barra de desplazamiento del div ha tocado fondo:

$('#someScrollingDiv').on('scroll', function() {
    let div = $(this).get(0);
    if(div.scrollTop + div.clientHeight >= div.scrollHeight) {
        // do the lazy loading here
    }
});
El coprolal
fuente
¡Gracias hermano! Esto realmente me ayudó :)
Raru
1

Pasé algún tiempo tratando de encontrar una buena función para envolver una solución. De todos modos, terminé con esto, que creo que es una mejor solución al cargar contenido múltiple en una sola página o en un sitio.

Función:

function ifViewLoadContent(elem, LoadContent)
    {
            var top_of_element = $(elem).offset().top;
            var bottom_of_element = $(elem).offset().top + $(elem).outerHeight();
            var bottom_of_screen = $(window).scrollTop() + window.innerHeight;
            var top_of_screen = $(window).scrollTop();

            if((bottom_of_screen > top_of_element) && (top_of_screen < bottom_of_element)){
            if(!$(elem).hasClass("ImLoaded"))   {
                $(elem).load(LoadContent).addClass("ImLoaded");
            }
            }
            else {
               return false;
            }
        }

Luego puede llamar a la función usando la ventana en el desplazamiento (por ejemplo, también puede vincularlo a un clic, etc., como también lo hago, de ahí la función):

Usar:

$(window).scroll(function (event) {
        ifViewLoadContent("#AjaxDivOne", "someFile/somecontent.html"); 

        ifViewLoadContent("#AjaxDivTwo", "someFile/somemorecontent.html"); 
    });

Este enfoque también debería funcionar para el desplazamiento de divs, etc. Espero que ayude, en la pregunta anterior, podría usar este enfoque para cargar su contenido en secciones, tal vez agregar y, por lo tanto, regatear todos esos datos de imagen en lugar de alimentación masiva.

Utilicé este enfoque para reducir la sobrecarga en https://www.taxformcalculator.com . Se acabó el truco, si miras el sitio e inspeccionas el elemento, etc., puedes ver el impacto en la carga de la página en Chrome (como ejemplo).

Pete - iCalculator
fuente
1

Mejora en la respuesta @deepakssn. Existe la posibilidad de que desee que los datos se carguen un poco antes de que realmente avancemos hacia la parte inferior .

var scrollLoad = true;
$(window).scroll(function(){
 if (scrollLoad && ($(document).height() - $(window).height())-$(window).scrollTop()<=800){
    // fetch data when we are 800px above the document end
    scrollLoad = false;
   }
  });

[var scrollLoad] se usa para bloquear la llamada hasta que se agreguen datos nuevos.

Espero que esto ayude.

Moonis Abidi
fuente