jQuery charge plus de données sur le défilement


148

Je me demande simplement comment puis-je implémenter plus de données sur le défilement uniquement si le div.loading est visible.

Habituellement, nous recherchons la hauteur de la page et la hauteur de défilement, pour voir si nous devons charger plus de données. mais l'exemple suivant est alors peu compliqué.

L'image suivante est un parfait exemple. il y a deux div .loading dans la liste déroulante. Lorsque l'utilisateur fait défiler le contenu, selon ce qui est visible, il devrait commencer à charger plus de données pour celui-ci.

entrez la description de l'image ici

Alors, comment puis-je savoir si .loading div est encore visible par l'utilisateur ou non? Je peux donc commencer à charger des données pour cette div uniquement.

Réponses:


286

Dans jQuery, vérifiez si vous avez atteint le bas de la page en utilisant la fonction de défilement. Une fois que vous avez atteint cet objectif, effectuez un appel ajax (vous pouvez afficher une image de chargement ici jusqu'à la réponse ajax) et obtenez le prochain ensemble de données, ajoutez-le au div. Cette fonction est exécutée lorsque vous faites défiler à nouveau la page.

$(window).scroll(function() {
    if($(window).scrollTop() == $(document).height() - $(window).height()) {
           // ajax call get data from server and append to the div
    }
});

5
Cette solution est excellente et la plus simple;) Vous pouvez améliorer ce code avec les lignes suivantes dans l'appel ajax: La new_element.hide().appendTo('.your_div').fadeIn(); $(window).scrollTop($(window).scrollTop()-1);première ligne ajoute des éléments de manière agréable, la seconde assure que votre fonction ne s'arrête jamais en bas de page.
alekwisnia

34
J'aborde cela de la même manière, en tenant compte du fait que vous avez toujours des éléments arbitraires (navigation) au bas de votre page et que vous voulez vraiment charger avant d'atteindre le bas. Donc ma fonction intérieure est: 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 a un excellent épisode à ce sujet: railscasts.com/episodes/114-endless-page . Il existe également une version révisée mais vous pourriez avoir besoin d'un abonnement.
Vee le

4
Si quelqu'un souhaite savoir si un utilisateur a fait défiler vers le bas, il peut utiliser cette condition if à l'intérieur du si celle affichée ici: if ($ (window) .scrollTop () + $ (window) .height () == $ (document ) .height ()) {console.log ('Défilé vers le bas!'); }
Roy Shoa

5
Cette réponse n'est pas celle que j'ai posée dans la question.
Basit le

84

Avez-vous entendu parler du plugin jQuery Waypoint .

Vous trouverez ci-dessous la manière simple d'appeler un plugin de waypoints et de faire charger la page plus de contenu une fois que vous atteignez le bas du scroll:

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

8
aucune chance d'une démonstration via jsfiddle?
cwiggo

4
bonne suggestion mais le pire waypoint du plugin js .. j'ai perdu beaucoup de temps .... la réponse ci-dessous était beaucoup plus rapide et plus rapide
Karan Datwani

2
Quelle réponse avez-vous trouvée la meilleure?
wuno

Vous pouvez vous référer à ma réponse pour l'implémentation de Lazy Loader. stackoverflow.com/a/45846766/2702249
Om Sao

9

Voici un exemple:

  1. En faisant défiler vers le bas, les éléments html sont ajoutés. Ce mécanisme d'ajout ne se fait que deux fois, puis un bouton de couleur bleu poudre est enfin ajouté.

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


@RohanAshik: Je viens de vérifier. Ça marche. Essayez de faire défiler jusqu'à la fin.
Om Sao le

@Om Prakash Sao Cela fonctionne bien ici, mais quand j'exécute ce code en sublime, l'événement fonctionne lorsque la barre de défilement atteint le haut et non le bas, \
geek le

8

La réponse acceptée à cette question a un problème avec le chrome lorsque la fenêtre est agrandie à une valeur> 100%. Voici le code recommandé par les développeurs de chrome dans le cadre d'un bug que j'avais soulevé sur le même.

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

Pour référence:

Question SO connexe

Bug de Chrome


7

Si tout votre document ne défile pas, par exemple, lorsque vous avez un défilement divdans le document, les solutions ci-dessus ne fonctionneront pas sans adaptations. Voici comment vérifier si la barre de défilement du div a atteint le bas:

$('#someScrollingDiv').on('scroll', function() {
    let div = $(this).get(0);
    if(div.scrollTop + div.clientHeight >= div.scrollHeight) {
        // do the lazy loading here
    }
});

Merci mec! Cela m'a vraiment aidé :)
Raru

1

J'ai passé du temps à essayer de trouver une fonction intéressante pour envelopper une solution. Quoi qu'il en soit, je me suis retrouvé avec ce que je pense être une meilleure solution lors du chargement de plusieurs contenus sur une seule page ou sur un site.

Fonction:

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

Vous pouvez ensuite appeler la fonction en utilisant window on scroll (par exemple, vous pouvez également la lier à un clic etc. comme je le fais aussi, d'où la fonction):

Utiliser:

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

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

Cette approche devrait également fonctionner pour faire défiler les divs, etc. J'espère que cela aide, dans la question ci-dessus, vous pouvez utiliser cette approche pour charger votre contenu dans des sections, peut-être ajouter et ainsi dribbler toutes ces données d'image plutôt que l'alimentation en masse.

J'ai utilisé cette approche pour réduire les frais généraux sur https://www.taxformcalculator.com . C'est mort le tour, si vous regardez le site et inspectez l'élément, etc., vous pouvez voir l'impact sur le chargement de la page dans Chrome (à titre d'exemple).


1

Amélioration de la réponse @deepakssn. Il est possible que vous souhaitiez que les données se chargent un peu avant de faire défiler vers le bas .

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] est utilisé pour bloquer l'appel jusqu'à ce qu'une nouvelle donnée soit ajoutée.

J'espère que cela t'aides.


En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.