jQuery carrega mais dados no scroll


148

Estou apenas querendo saber como posso implementar mais dados na rolagem apenas se o div.loading estiver visível.

Geralmente, procuramos a altura da página e a altura da rolagem, para ver se precisamos carregar mais dados. mas o exemplo a seguir é um pouco complicado, então isso.

A imagem a seguir é um exemplo perfeito. existem duas divs de carregamento na caixa suspensa. Quando o usuário rola o conteúdo, o que estiver visível, deve começar a carregar mais dados.

insira a descrição da imagem aqui

Então, como posso descobrir se .loading div ainda está visível para o usuário ou não? Para que eu possa começar a carregar dados apenas para essa div.

Respostas:


286

No jQuery, verifique se você atingiu o final da página usando a função de rolagem. Depois de acertar, faça uma chamada ajax (você pode mostrar uma imagem de carregamento aqui até a resposta ajax) e obtenha o próximo conjunto de dados, anexando-o à div. Esta função é executada quando você rolar a página novamente.

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

5
Essa solução é ótima e a mais simples;) Você pode melhorar esse código com as seguintes linhas na chamada ajax: A new_element.hide().appendTo('.your_div').fadeIn(); $(window).scrollTop($(window).scrollTop()-1);primeira linha acrescenta elementos de maneira agradável, a segunda garante que sua função nunca pare na parte inferior da página.
Alekwisnia #

34
Abordo isso de maneira semelhante, levando em consideração o fato de que você sempre tem coisas arbitrárias (navegação) na parte inferior da página e deseja realmente carregar antes de chegar ao fundo. Assim, a minha função interna é: 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 tem um excelente episódio sobre isso: railscasts.com/episodes/114-endless-page . Há também uma versão revisada, mas você pode precisar de uma assinatura.
Vee

4
Se alguém quiser saber se um usuário rolou para baixo, pode usar esta condição if dentro da if exibida aqui: if ($ (window) .scrollTop () + $ (window) .height () == $ (document ) .height ()) {console.log ('Rolou para a parte inferior!'); }
Roy Shoa

5
Esta resposta não é o que eu perguntei na pergunta.
Basit 28/02

84

Você já ouviu falar sobre o plugin jQuery Waypoint .

Abaixo está a maneira simples de chamar um plug-in de waypoints e fazer com que a página carregue mais conteúdo quando você chegar ao final da rolagem:

$(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
alguma chance de uma demonstração via jsfiddle?
Cwiggo

4
boa sugestão, mas o pior waypoint do plugin js .. perdi muito tempo .... a resposta abaixo foi muito mais rápida e rápida
Karan Datwani

2
Qual resposta abaixo você achou ser a melhor?
wuno 12/02

Você pode consultar minha resposta para a implementação do Lazy Loader. stackoverflow.com/a/45846766/2702249
Om Sao

9

Aqui está um exemplo:

  1. Ao rolar para a parte inferior, os elementos html são anexados. Esse mecanismo de anexação é feito apenas duas vezes e, em seguida, um botão com a cor azul em pó é finalmente anexado.

<!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: Acabei de verificar. Está funcionando. Tente rolar para baixo até o fim.
Om Sao

@ Prakash Sao Seu funcionando bem aqui, mas quando executo esse código em sublime, o evento funciona quando a barra de rolagem atinge o topo e não o fundo, \
geeky

8

A resposta aceita para esta pergunta tem algum problema com o chrome quando a janela é ampliada para um valor> 100%. Aqui está o código recomendado pelos desenvolvedores do Chrome como parte de um bug que eu criei no mesmo.

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

Para referência:

Pergunta SO relacionada

Bug do Chrome


7

Se nem todos os seus documentos rolarem, digamos, quando você tiver uma rolagem divno documento, as soluções acima não funcionarão sem adaptações. Veja como verificar se a barra de rolagem do div atingiu o fundo:

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

Obrigado mano! Isso realmente me ajudou :)
Raru 05/04

1

Passei algum tempo tentando encontrar uma boa função para embrulhar uma solução. Enfim, acabei com isso que considero uma solução melhor ao carregar vários conteúdos em uma única página ou em um site.

Função:

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

Você pode chamar a função usando window on scroll (por exemplo, você também pode vinculá-la a um clique etc., como eu também faço, daí a função):

Usar:

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

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

Essa abordagem também deve funcionar para rolar divs etc. Espero que ajude, na pergunta acima você pode usar essa abordagem para carregar seu conteúdo em seções, talvez acrescentar e assim driblar alimentar todos os dados de imagem em vez de alimentar em massa.

Usei essa abordagem para reduzir a sobrecarga em https://www.taxformcalculator.com . O truque acabou, se você olhar o site e inspecionar o elemento etc., poderá ver o impacto no carregamento da página no Chrome (como exemplo).


1

Melhorando na resposta @deepakssn. É possível que você queira que os dados sejam carregados um pouco antes de realmente rolarmos para o final .

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] é usado para bloquear a chamada até que um novo dado seja anexado.

Espero que isto ajude.


Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.