Detectar se a página terminou de carregar

91

Existe uma maneira de detectar quando uma página termina de carregar, ou seja, todo o seu conteúdo, javascript e ativos como css e imagens?

assim como:

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

e também, se a página estiver carregando por mais de um minuto, faça algo como:

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

Já vi sites como o MobileMe da Apple fazer verificações semelhantes, mas não consegui descobrir em suas enormes bibliotecas de código.

Alguém pode ajudar?

obrigado

EDIT: Isto é essencialmente o que eu quero fazer:

// 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
fonte
2
Existe uma razão para que window.onload(ou $(window).load()) não funcione?
sdleihssirhc de
Olá, @Cameron. Qual código funciona para ocultar o carregador depois que a página termina de carregar?
tnkh
@TonyNg Veja minha resposta: stackoverflow.com/questions/7083693/…
Cameron

Respostas:

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

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

});

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

Veja também http://api.jquery.com/load-event/ para uma explicação sobre o jQuery (janela) .load.

Atualizar

Uma explicação detalhada sobre como funciona o carregamento de javascript e os dois eventos DOMContentLoaded e OnLoad pode ser encontrada nesta página .

DOMContentLoaded : quando o DOM está pronto para ser manipulado. A maneira da jQuery de capturar esse evento é com jQuery(document).ready(function () {});.

OnLoad : quando o DOM está pronto e todos os recursos - incluindo imagens, iframe, fontes, etc. - foram carregados e a roda giratória / classe de horas desaparece. A maneira da jQuery de capturar este evento é a mencionada acima jQuery(window).load.

TJ.
fonte
Se você olhar para o meu OP, eu o alterei para que ele mostre quais são meus objetivos. Então, essencialmente, eu quero mostrar a página depois que todos os recursos forem carregados e fade out em um carregador e fade no conteúdo. Meu código funcionaria corretamente? Saúde
Cameron
Seu código parece bom, mas eu teria que vê-lo em ação para ter certeza.
TJ.
@Jimmer Sim: MDN : "O evento de carregamento é disparado quando um recurso e seus recursos dependentes terminam de carregar."
TJ.
2
Observe que jQuery.load()foi descontinuado desde jQuery / 1.8 e removido do jQuery / 3. A sintaxe atual é jQuery(window).on("load", function(){/*...*/});.
Álvaro González
58

Existem duas maneiras de fazer isso no jquery, dependendo do que você está procurando.

usando jquery você pode fazer

  • // isso vai esperar que os ativos de texto sejam carregados antes de chamar isso (o dom .. css .. js)

    $(document).ready(function(){...});
  • // isso vai esperar que todas as imagens e ativos de texto terminem de carregar antes de executar

    $(window).load(function(){...});
samccone
fonte
Nesse método, como você pode saber se a página está carregando há vários minutos, mas ainda não está completa?
yoozer8 de
2
isso pode ser realizado com setTimeout (function () {! carregado && foo ();}, 20000); e definido carregado como verdadeiro no doc pronto ou carregamento de janela
samccone
1
para jquery 3.0 use $ (window) .on ("load", function (e) {});
zero8 de
13

Isso é chamado de onload. O DOM pronto foi, na verdade, criado pelo motivo exato em que o onload esperou pelas imagens. (Resposta retirada de Matchu em uma pergunta semelhante há algum tempo.)

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

onload espera por todos os recursos que fazem parte do documento.

Link para uma pergunta onde ele explicou tudo:

Clique em mim, você sabe que quer!

Nemanja
fonte
10

Eu acho que a maneira mais fácil seria

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

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

EDITAR, para ser um pouco louco:

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
fonte
Eu meio que gosto dessa ideia, NO ENTANTO, os itenslen nunca parecem fazer a contagem regressiva até 0.
Banido em
1
CUIDADO COM ESTE MÉTODO - Ele assume que todos os elementos listados têm um evento 'load', o que muitos deles no exemplo não têm.
John Wedgbury
6

Outra opção você pode verificar o document.readyState como,

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

A partir da documentação da página readyState, o resumo do estado completo é

Retorna "carregando" enquanto o documento está carregando, "interativo" quando termina a análise, mas ainda carrega os sub-recursos, e "completo" depois de carregado.

Rohan Kumar
fonte
Tenho tido problemas com imagens em cache, e este parece ser o melhor código para isso em desempenho ... Quer saber sobre a prática? Parece ser melhor que o jQuery $(window).on("load" function () {//dostuff})...?
kmkmkm
3

Uma opção é deixar a página em branco, contendo uma pequena quantidade de javascript. Use o script para fazer uma chamada AJAX para obter o conteúdo real da página e fazer com que a função de sucesso escreva o resultado sobre o documento atual. Na função de tempo limite, você pode "fazer outra coisa incrível"

Pseudocódigo aproximado:

$(document).ready(function(){
    $.ajax
      url of actual page
      success:do something amazing
      timeout: do something else
});
yoozer8
fonte
Sim, ele é. Mas é a primeira maneira que me veio à mente quando me perguntei "Como uma página pode saber se um pedido para ela atinge o tempo limite?"
yoozer8 de
bem, ele não dirá se as imagens terminaram de carregar .. ao contrário, ele apenas dirá se a marcação bruta foi carregada
samccone
Hm. Isso me leva a uma pergunta interessante. Se você apenas fizesse $ (document) .html (resposta), e a resposta contivesse um document.ready ou um window.load, isso seria executado depois que o documento fosse escrito? Ou o navegador veria a página como já carregada e não os chamaria na mudança de conteúdo?
yoozer8 de
Acho que vou chamá-lo uma segunda vez, mas não 100% ... experimente
samccone
2

É isso que você tinha em mente?

$("document").ready( function() {
    // do your stuff
}
John smith
fonte
1
Isso será executado quando o DOM estiver pronto, mas pode ser antes que coisas como imagens terminem de carregar.
James Allardice
2

Sem jquery ou algo parecido, porque por que não?

var loaded=0;
var loaded1min=0;
document.addEventListener("DOMContentLoaded", function(event) {
   loaded=1;
    setTimeout(function () {
      loaded1min=1;
    }, 60000);
});
Cth103
fonte
Isso é correto, mas um pouco diferente do que jqueryfunciona. DOMContentLoadedé acionado somente depois que o conteúdo externo é carregado (principalmente imagens, que podem demorar muito em certas condições). jqueryexecuta .ready()usando eventos específicos do navegador, que (na maioria dos navegadores) acontecem antes que o conteúdo externo seja carregado.
grochmal de
1

Para sua informação, de pessoas que perguntaram nos comentários, isto é o que eu realmente usei em projetos:

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
fonte