jQuery ładuje więcej danych na scroll

148

Zastanawiam się tylko, jak zaimplementować więcej danych na przewijaniu tylko wtedy, gdy widoczny jest div.loading.

Zwykle szukamy wysokości strony i wysokości przewijania, aby sprawdzić, czy musimy załadować więcej danych. ale poniższy przykład jest wtedy trochę skomplikowany.

Poniższy obraz jest doskonałym przykładem. na liście rozwijanej znajdują się dwa elementy div .loading. Kiedy użytkownik przewija zawartość, cokolwiek jest widoczne, powinno zacząć ładować więcej danych.

wprowadź opis obrazu tutaj

Jak więc mogę się dowiedzieć, czy .loading div jest jeszcze widoczny dla użytkownika, czy nie? Więc mogę rozpocząć ładowanie danych tylko dla tego div.

Basit
źródło

Odpowiedzi:

286

W jQuery sprawdź, czy trafiłeś na dół strony za pomocą funkcji przewijania. Kiedy już to zrobisz, wykonaj wywołanie Ajax (możesz tu wyświetlić obraz ładowania do czasu odpowiedzi AJAX) i pobierz następny zestaw danych, dołącz go do div. Ta funkcja jest wykonywana podczas ponownego przewijania strony w dół.

$(window).scroll(function() {
    if($(window).scrollTop() == $(document).height() - $(window).height()) {
           // ajax call get data from server and append to the div
    }
});
deepakssn
źródło
5
To rozwiązanie jest świetne i najprostsze;) Możesz ulepszyć ten kod za pomocą następujących linii w wywołaniu Ajax: new_element.hide().appendTo('.your_div').fadeIn(); $(window).scrollTop($(window).scrollTop()-1);Pierwsza linia ładnie dołącza elementy, druga zapewnia, że ​​twoja funkcja nigdy nie zatrzymuje się na dole strony.
alekwisnia
34
Podchodzę do tego w podobny sposób, biorąc pod uwagę fakt, że zawsze masz dowolne elementy (nawigację) na dole strony i naprawdę chcesz załadować, zanim dotrzesz na sam dół. Więc moja wewnętrzna funkcja to: 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 ma na ten temat doskonały odcinek: railscasts.com/episodes/114-endless-page . Istnieje również poprawiona wersja, ale możesz potrzebować subskrypcji.
Vee
4
Jeśli ktoś chciałby wiedzieć, czy użytkownik przewinął na dół, może użyć tego warunku if wewnątrz wyświetlonego tutaj warunku if: if ($ (window) .scrollTop () + $ (window) .height () == $ (document ) .height ()) {console.log ('Przewiń do dołu!'); }
Roy Shoa
5
Ta odpowiedź nie jest tym, o co zadałem w pytaniu.
Basit
84

Słyszałeś o plugin jQuery Waypoint .

Poniżej znajduje się prosty sposób wywołania wtyczki punktów orientacyjnych i załadowania strony więcej treści po osiągnięciu dna podczas przewijania:

$(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
źródło
8
jest szansa na demonstrację przez jsfiddle?
cwiggo
4
dobra sugestia, ale najgorszy punkt orientacyjny wtyczki js .. zmarnowałem dużo czasu ... odpowiedź poniżej była znacznie szybsza i szybsza
Karan Datwani
2
Która z poniższych odpowiedzi jest dla Ciebie najlepsza?
wuno
Możesz zapoznać się z moją odpowiedzią na temat implementacji Lazy Loadera. stackoverflow.com/a/45846766/2702249
Om Sao
9

Oto przykład:

  1. Po przewinięciu w dół elementy html są dodawane. Ten mechanizm dopinania jest wykonywany tylko dwa razy, a następnie dołączany jest w końcu przycisk w kolorze pudroniebieskim.

<!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
źródło
@RohanAshik: Właśnie sprawdziłem. To działa. Spróbuj przewinąć w dół do końca.
Om Sao
@Om Prakash Sao Działa dobrze tutaj, ale kiedy uruchamiam ten kod w wysublimowany sposób, zdarzenie działa, gdy pasek przewijania uderza w górę, a nie na dół, \
geeky
8

Przyjęta odpowiedź na to pytanie wiąże się z pewnym problemem z chromem, gdy okno jest powiększone do wartości> 100%. Oto kod zalecany przez programistów chrome jako część błędu, który zgłosiłem na tym samym.

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

Na przykład:

Powiązane pytanie SO

Błąd Chrome

Prasanth KC
źródło
7

Jeśli nie cały dokument jest przewijany, powiedzmy, gdy przewijasz się divw dokumencie, powyższe rozwiązania nie będą działać bez dostosowań. Oto jak sprawdzić, czy pasek przewijania div dotarł do dołu:

$('#someScrollingDiv').on('scroll', function() {
    let div = $(this).get(0);
    if(div.scrollTop + div.clientHeight >= div.scrollHeight) {
        // do the lazy loading here
    }
});
Coprolal
źródło
Dzięki stary! To naprawdę mi pomogło :)
Raru
1

Spędziłem trochę czasu, próbując znaleźć fajną funkcję do pakowania rozwiązania. W każdym razie skończyło się na tym, co uważam za lepsze rozwiązanie podczas ładowania wielu treści na jednej stronie lub w całej witrynie.

Funkcjonować:

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

Możesz wtedy wywołać funkcję za pomocą okna przy przewijaniu (na przykład możesz również powiązać ją z kliknięciem itp., Tak jak ja też to robię, stąd funkcja):

Używać:

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

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

To podejście powinno również działać w przypadku przewijanych elementów div itp. Mam nadzieję, że pomoże, w powyższym pytaniu możesz użyć tego podejścia do ładowania treści w sekcjach, może dołączać i tym samym dryblować wszystkie dane obrazu, a nie zbiorczy kanał.

Zastosowałem to podejście, aby zmniejszyć obciążenie na https://www.taxformcalculator.com . Nie udało się, jeśli spojrzysz na stronę i sprawdzisz element itp., Możesz zobaczyć wpływ na ładowanie strony w Chrome (jako przykład).

Pete - iCalculator
źródło
1

Poprawa odpowiedzi @deepakssn. Istnieje możliwość, że chcesz trochę załadować dane, zanim faktycznie przewiniemy do dołu .

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] służy do blokowania połączenia do czasu dołączenia nowych danych.

Mam nadzieję że to pomoże.

Moonis Abidi
źródło
0

Twoje pytanie dotyczy w szczególności ładowania danych, gdy pojawia się element div , a nie gdy użytkownik dotrze do końca strony.

Oto najlepsza odpowiedź na Twoje pytanie: https://stackoverflow.com/a/33979503/3024226

Ihsan
źródło