Wykryj, czy strona się ładuje

93

Czy istnieje sposób na wykrycie zakończenia ładowania strony, tj. Całej jej zawartości, kodu JavaScript i zasobów, takich jak css i obrazy?

tak jak:

if(PAGE HAS FINISHED LOADING)
{
// do something amazing
}

a także dodatkowo, jeśli strona ładowała się dłużej niż 1 minutę, zrób coś innego, na przykład:

if(PAGE HAS BEEN LOADING FOR 1 MIN)
{
// do something else amazing
}

Widziałem witryny internetowe, takie jak MobileMe firmy Apple, przeprowadzające podobne kontrole, ale nie byłem w stanie tego rozgryźć w ich ogromnych bibliotekach kodu.

Czy ktoś może pomóc?

Dzięki

EDYCJA: Zasadniczo chcę to zrobić:

// hide content
$("#hide").hide();

// hide loading
$("#loading").hide();

// fade in loading animation
setTimeout($('#loading').fadeIn(), 200);

jQuery(window).load(function() {
  $("#hide").fadeIn();

  $("#loading").fadeOut(function() {
    $(this).remove();
    clearInterval(loadingAnim);
  });

  setTimeout(function() {
    $("#error").fadeIn();
  }, 60000);
});
Cameron
źródło
2
Czy istnieje powód, dla którego window.onload(lub $(window).load()) nie zadziała?
sdleihssirhc
Cześć @Cameron. Który kod działa, aby ukryć moduł ładujący po zakończeniu ładowania strony?
tnkh
@TonyNg Zobacz moją odpowiedź: stackoverflow.com/questions/7083693/…
Cameron

Odpowiedzi:

129
jQuery(window).load(function () {
    alert('page is loaded');

    setTimeout(function () {
        alert('page is loaded and 1 minute has passed');   
    }, 60000);

});

Lub http://jsfiddle.net/tangibleJ/fLLrs/1/

Zobacz także http://api.jquery.com/load-event/, aby uzyskać wyjaśnienie dotyczące jQuery (okno) .load.

Aktualizacja

Szczegółowe wyjaśnienie, jak działa ładowanie javascript oraz dwa zdarzenia DOMContentLoaded i OnLoad, można znaleźć na tej stronie .

DOMContentLoaded : kiedy DOM jest gotowy do manipulacji. Metoda jQuery na przechwytywanie tego zdarzenia polega na jQuery(document).ready(function () {});.

OnLoad : gdy DOM jest gotowy i wszystkie zasoby - w tym obrazy, elementy iframe, czcionki itp. - zostały załadowane, a obracające się koło / klasa godzin znikają. Sposób, w jaki jQuery przechwytuje to wydarzenie, jest wspomniany powyżej jQuery(window).load.

T. Junghans
źródło
Jeśli spojrzysz na mój PO, poprawiłem go tak, aby pokazywał, jakie są moje cele. Tak więc zasadniczo chcę pokazać stronę po załadowaniu wszystkich zasobów, zniknięciu modułu ładującego i zaniknięciu zawartości. Czy mój kod będzie działał poprawnie? Pozdrawiam
Cameron
Twój kod wygląda dobrze, ale musiałbym zobaczyć go w akcji, żeby mieć pewność.
T. Junghans
@Jimmer Tak: MDN : "Zdarzenie ładowania jest uruchamiane, gdy zasób i jego zasoby zależne zakończyły się ładowanie."
T. Junghans
2
Należy pamiętać, że jQuery.load()zostało to przestarzałe od wersji jQuery / 1.8 i usunięte w jQuery / 3. Obecna składnia to jQuery(window).on("load", function(){/*...*/});.
Álvaro González
59

w jquery można to zrobić na dwa sposoby, w zależności od tego, czego szukasz.

używając jquery, możesz to zrobić

  • // to będzie czekać na załadowanie zasobów tekstowych przed wywołaniem this (dom .. css .. js)

    $(document).ready(function(){...});
    
  • // to będzie czekać na zakończenie ładowania wszystkich obrazów i zasobów tekstowych przed wykonaniem

    $(window).load(function(){...});
    
samccone
źródło
W jaki sposób w tej metodzie można stwierdzić, czy strona ładowała się od kilku minut, ale nie została jeszcze ukończona?
yoozer8
2
można to osiągnąć za pomocą metody setTimeout (function () {! załadowano && foo ();}, 20000); i ustawiono załadowany na true w dokumencie gotowym lub załadowaniu okna
samccone
1
dla jquery 3.0 użyj $ (window) .on ("load", function (e) {});
zero8
13

To się nazywa onload. Gotowy model DOM został stworzony dokładnie z tego powodu, że ładowanie czekało na obrazy. (Odpowiedź pochodzi z Matchu na podobne pytanie jakiś czas temu.)

window.onload = function () { alert("It's loaded!") }

onload czeka na wszystkie zasoby, które są częścią dokumentu.

Link do pytania, w którym wszystko wyjaśnił:

Kliknij mnie, wiesz, że chcesz!

Nemanja
źródło
10

Myślę, że najłatwiej byłoby

var items = $('img, style, ...'), itemslen = items.length;

items.bind('load', function(){ 
    itemslen--;
    if (!itemlen) // Do stuff here
});

EDYTUJ, żeby być trochę szalonym:

var items = $('a, abbr, acronym, address, applet, area, audio, b, base, ' + 
    'basefont, bdo, bgsound, big, body, blockquote, br, button, canvas, ' + 
    'caption, center, cite, code, col, colgroup, comment, custom, dd, del, ' +
    'dfn, dir, div, dl, document, dt, em, embed, fieldset, font, form, frame, ' +
    'frameset, head, hn, hr, html, i, iframe, img, input, ins, isindex, kbd, ' +
    'label, legend, li, link, listing, map, marquee, media, menu, meta, ' +
    'nextid, nobr, noframes, noscript, object, ol, optgroup, option, p, ' +
    'param, plaintext, pre, q, rt, ruby, s, samp, script, select, small, ' + 
    'source, span, strike, strong, style, sub, sup, table, tbody, td, ' + 
    'textarea, tfoot, th, thead, title, tr, tt, u, ul, var, wbr, video, ' + 
    'window, xmp'), itemslen = items.length;

items.bind('load', function(){ 
    itemslen--;
    if (!itemlen) // Do stuff here
});
qwertymk
źródło
Trochę mi się podoba ten pomysł JEDNAK itemlen nigdy nie wydaje się odliczać do zera
Banowanie
1
UWAŻAJ NA TĘ METODĘ - Zakłada się, że wszystkie wymienione elementy mają zdarzenie „load”, czego wiele z nich w przykładzie nie ma.
John Wedgbury
6

Inną opcją możesz sprawdzić dokument. ReadyState like,

var chkReadyState = setInterval(function() {
    if (document.readyState == "complete") {
        // clear the interval
        clearInterval(chkReadyState);
        // finally your page is loaded.
    }
}, 100);

Z dokumentacji strony readyState podsumowanie kompletnego stanu to

Zwraca „ładowanie” podczas wczytywania dokumentu, „interaktywne” po zakończeniu przetwarzania, ale nadal ładuje zasoby podrzędne, oraz „zakończone” po załadowaniu.

Rohan Kumar
źródło
Miałem problemy z obrazami w pamięci podręcznej i wydaje się, że jest to lepszy kod do tego pod względem wydajności ... Zastanawiasz się nad praktyką? Wydaje się być lepsze niż jQuery $(window).on("load" function () {//dostuff})...?
kmkmkm
3

Jedną z opcji jest pozostawienie pustej strony, zawierającej niewielką ilość kodu JavaScript. Użyj skryptu, aby wykonać wywołanie AJAX w celu uzyskania rzeczywistej zawartości strony, a funkcja sukcesu zapisze wynik w bieżącym dokumencie. W funkcji timeout możesz „zrobić coś jeszcze niesamowitego”

Przybliżony pseudokod:

$(document).ready(function(){
    $.ajax
      url of actual page
      success:do something amazing
      timeout: do something else
});
yoozer8
źródło
Tak to jest. Ale to pierwszy sposób, który przyszedł mi do głowy, gdy zadałem sobie pytanie: „Jak strona może stwierdzić, czy upłynął limit czasu żądania?”
yoozer8
cóż, nie powie ci, czy obraz się zakończył ładowanie .. raczej powie tylko, czy surowy znacznik został załadowany
samccone
Hm. Prowadzi mnie do interesującego pytania. Jeśli właśnie zrobiłeś $ (document) .html (odpowiedź), a odpowiedź zawierałaby document.ready lub window.load, czy to się wykonało po napisaniu dokumentu? A może przeglądarka zobaczy stronę jako już załadowaną i nie wywoła jej po zmianie treści?
yoozer8
Myślę, że nazywają go po raz drugi, ale nie 100% ... go wypróbować
samccone
2

Czy to właśnie miałeś na myśli?

$("document").ready( function() {
    // do your stuff
}
John Smith
źródło
1
Uruchomi się, gdy DOM będzie gotowy, ale może to nastąpić przed zakończeniem ładowania obrazów.
James Allardice,
2

Bez jQuery lub czegoś podobnego, bo czemu nie?

var loaded=0;
var loaded1min=0;
document.addEventListener("DOMContentLoaded", function(event) {
   loaded=1;
    setTimeout(function () {
      loaded1min=1;
    }, 60000);
});
Cth103
źródło
1
To jest poprawne, ale nieco różni się od tego, co jquerydziała. DOMContentLoadedjest uruchamiany dopiero po załadowaniu zawartości zewnętrznej (zwłaszcza obrazów, co może zająć dużo czasu w określonych warunkach). jquerywykonuje .ready()za pomocą zdarzeń specyficznych dla przeglądarki, które (w większości przeglądarek) mają miejsce przed załadowaniem zawartości zewnętrznej.
grochmal
1

FYI osób, które pytały w komentarzach, właśnie tego użyłem w projektach:

function onLoad(loading, loaded) {
    if(document.readyState === 'complete'){
        return loaded();
    }
    loading();
    if (window.addEventListener) {
        window.addEventListener('load', loaded, false);
    }
    else if (window.attachEvent) {
        window.attachEvent('onload', loaded);
    }
};

onLoad(function(){
   console.log('I am waiting for the page to be loaded');
},
function(){
    console.log('The page is loaded');
});
Cameron
źródło