window.onload vs document.onload

711

Qual é o suporte mais amplo: window.onloadou document.onload?

Chris Ballance
fonte
2
Os documentos MDN explicam esses windoweventos: onloade DOMContentLoaded. Exemplo de uso :, window.addEventListener('DOMContentLoaded', callback). A partir de meados de 2019, compatível com todos os principais navegadores. ----- developer.mozilla.org/en-US/docs/Web/API/Window/… ------ developer.mozilla.org/en-US/docs/Web/API/Window/load_event
Craig Hicks
Ainda para mim, no Firefox 75.0 hoje, window.onloade document.onloadsão diferentes um do outro! window.onloadparece ocorrer depois e tem um pouco mais de carga do que document.onload! (Algumas coisas estão funcionando com a janela que não está funcionando com o documento! Isso vale para document.onreadstatechange 'complete' também!)
Andrew

Respostas:

723

Quando eles disparam?

window.onload

  • Por padrão, é acionado quando a página inteira é carregada, incluindo seu conteúdo (imagens, CSS, scripts etc.).

Em alguns navegadores, agora assume o papel document.onloade é acionado quando o DOM também está pronto.

document.onload

  • É chamado quando o DOM está pronto, o que pode ser anterior às imagens e outro conteúdo externo é carregado.

Quão bem eles são suportados?

window.onloadparece ser o mais amplamente suportado. Na verdade, alguns dos navegadores mais modernos têm em um sentido substituído document.onloadcom window.onload.

Os problemas de suporte ao navegador são provavelmente o motivo pelo qual muitas pessoas estão começando a usar bibliotecas como o jQuery para lidar com a verificação do documento estar pronto, da seguinte forma:

$(document).ready(function() { /* code here */ });
$(function() { /* code here */ });

Para os propósitos da história. window.onloadvs body.onload:

Uma pergunta semelhante foi feita nos fóruns de codificação há algum tempo sobre o uso de window.onloadmais de um body.onload. O resultado parecia ser que você deveria usá- window.onloadlo porque é bom separar sua estrutura da ação.

Josh Mein
fonte
25
Na verdade, essa afirmação parece ser direcionada a uma escolha entre window.onloade <body onload="">que é completamente diferente (e a "estrutura separada da ação" faz muito mais sentido nesse contexto). Não que a resposta esteja errada, mas a base dela é.
precisa saber é o seguinte
2
Essa citação é gramaticalmente horrível ... alguma edição (marcada) não deveria ajudar?
Kheldar
@ Thor84no Eu finalmente encontrei tempo para olhar e dar uma outra olhada nisso. Fiz algumas melhorias.
Josh Mein
@Kheldar, decidi parafrasear a citação, pois era bastante difícil.
Josh Mein
@ JoshMein Isso significa que document.onloadé equivalente a jQuery em JS document.ready?
John cj
276

A idéia geral é que window.onload seja acionado quando a janela do documento estiver pronta para apresentação e document.onload for acionado quando a árvore DOM (criada a partir do código de marcação no documento) for concluída .

Idealmente, a inscrição em eventos na árvore DOM permite manipulações fora da tela por meio de Javascript, incorrendo em quase nenhuma carga da CPU . Por outro lado, window.onloadpode demorar um pouco para disparar , quando vários recursos externos ainda precisam ser solicitados, analisados ​​e carregados.

► Cenário de teste:

Para observar a diferença e como o navegador escolhido implementa os manipuladores de eventos mencionados acima , basta inserir o seguinte código na <body>tag - - do documento .

<script language="javascript">
window.tdiff = []; fred = function(a,b){return a-b;};
window.document.onload = function(e){ 
    console.log("document.onload", e, Date.now() ,window.tdiff,  
    (window.tdiff[0] = Date.now()) && window.tdiff.reduce(fred) ); 
}
window.onload = function(e){ 
    console.log("window.onload", e, Date.now() ,window.tdiff, 
    (window.tdiff[1] = Date.now()) && window.tdiff.reduce(fred) ); 
}
</script>

►Resultado:

Aqui está o comportamento resultante, observável no Chrome v20 (e provavelmente nos navegadores mais atuais).

  • Nenhum document.onloadevento.
  • onloaddispara duas vezes quando declarado dentro de <body>, uma vez quando declarado dentro de <head>(onde o evento atua como document.onload).
  • contar e agir de acordo com o estado do contador permite emular os dois comportamentos de eventos.
  • Como alternativa, declare o window.onloadmanipulador de eventos dentro dos limites do <head>elemento HTML .

►Exemplo do projeto:

O código acima é retirado da base de código deste projeto ( index.htmle keyboarder.js).


Para obter uma lista dos manipuladores de eventos do objeto window , consulte a documentação do MDN.

Lorenz Lo Sauer
fonte
142

Adicionar ouvinte de evento

<script type="text/javascript">
  document.addEventListener("DOMContentLoaded", function(event) {
      // - Code to execute when all DOM content is loaded. 
      // - including fonts, images, etc.
  });
</script>


Update March 2017

1 JavaScript baunilha

window.addEventListener('load', function() {
    console.log('All assets are loaded')
})


2 jQuery

$(window).on('load', function() {
    console.log('All assets are loaded')
})


Boa sorte.

Akash
fonte
14
"O evento DOMContentLoaded é acionado quando o documento HTML inicial é completamente carregado e analisado, sem aguardar folhas de estilo, imagens e sub-quadros para concluir o carregamento." - developer.mozilla.org/en/docs/Web/Events/DOMContentLoaded Portanto, você parece estar incorreto sobre tudo o que está sendo carregado neste evento.
ProfK 29/03
2
@ Profof, obrigado pelo seu feedback. Você pode tentar window.addEventListener('load', function() {...}). Também atualizei minha resposta.
Akash 30/03
4
O que eu gosto nessa resposta é que ela fornece uma solução javascript simples e antiga. Você acha que a maioria das pessoas pensa que o jQuery está incorporado em todos os navegadores, considerando a frequência com que é fornecido como a única resposta.
Dave Terra
Problema duplo quando o maldito jquery leva muito tempo para carregar e você recebe $ não encontrado. Sou da opinião de que as soluções do tipo $ (window) .ready NUNCA devem ser confiáveis ​​para funcionar.
Shayne
1
Eu tentei tanto no chrome de hoje. Não está esperando por css e fontes.
MovAX13h 10/10
78

De acordo com a análise de documentos HTML - O final ,

  1. O navegador analisa a fonte HTML e executa scripts adiados.

  2. A DOMContentLoadedé despachado no documentmomento em que todo o HTML foi analisado e executado. O evento borbulha para o window.

  3. O navegador carrega recursos (como imagens) que atrasam o evento de carregamento.

  4. Um loadevento é despachado no window.

Portanto, a ordem de execução será

  1. DOMContentLoadedouvintes de eventos windowna fase de captura
  2. DOMContentLoaded ouvintes de eventos de document
  3. DOMContentLoadedouvintes de eventos windowna fase da bolha
  4. loadouvintes de eventos (incluindo onloadmanipulador de eventos) dewindow

Um loadouvinte de evento de bolha (incluindo onloadmanipulador de eventos) documentnunca deve ser chamado. Somente loadouvintes de captura podem ser chamados, mas devido ao carregamento de um sub-recurso como uma folha de estilo, não devido ao carregamento do próprio documento.

window.addEventListener('DOMContentLoaded', function() {
  console.log('window - DOMContentLoaded - capture'); // 1st
}, true);
document.addEventListener('DOMContentLoaded', function() {
  console.log('document - DOMContentLoaded - capture'); // 2nd
}, true);
document.addEventListener('DOMContentLoaded', function() {
  console.log('document - DOMContentLoaded - bubble'); // 2nd
});
window.addEventListener('DOMContentLoaded', function() {
  console.log('window - DOMContentLoaded - bubble'); // 3rd
});

window.addEventListener('load', function() {
  console.log('window - load - capture'); // 4th
}, true);
document.addEventListener('load', function(e) {
  /* Filter out load events not related to the document */
  if(['style','script'].indexOf(e.target.tagName.toLowerCase()) < 0)
    console.log('document - load - capture'); // DOES NOT HAPPEN
}, true);
document.addEventListener('load', function() {
  console.log('document - load - bubble'); // DOES NOT HAPPEN
});
window.addEventListener('load', function() {
  console.log('window - load - bubble'); // 4th
});

window.onload = function() {
  console.log('window - onload'); // 4th
};
document.onload = function() {
  console.log('document - onload'); // DOES NOT HAPPEN
};

Oriol
fonte
Eu executei seu snippet e document - load - capture, de fato, acontece, o que é contrário ao que eu esperava na minha pesquisa, sobre o motivo pelo qual o carregamento de documentos não está acontecendo para mim. Estranhamente, é inconsistente. Às vezes aparece, às vezes não, às vezes aparece duas vezes - mas nunca document - load - bubbleacontece. Eu sugeriria não usar document load.
Erroric
@erroric Bom argumento. Não considero que um loadevento seja despachado com recursos externos. Esse evento não borbulha e, portanto, geralmente não é detectado no documento, mas deve ocorrer na fase de captura. Essas entradas se referem à carga dos elementos <style>e <script>. Acho que o Edge está certo em mostrá-los e o Firefox e o Chrome estão errados.
Oriol
Obrigado Oriol, a useCaptureopção me ensinou algo novo.
Paul Watson
Obrigado por resumir o fluxo de análise e renderização do w3. Eu me pergunto após a etapa 4, uma vez que o evento 'load' é acionado, o que mais pode acontecer? Percebi no meu navegador que às vezes ainda existem alguns objetos sendo buscados após o acionamento do evento de carregamento, embora eu não tenha tocado ou interagido com a página. Você sabe como são chamados esses objetos? 'Objetos de renderização sem bloqueio?
weefwefwqg3 27/04
12

No Chrome, window.onload é diferente de <body onload="">, enquanto são iguais no Firefox (versão 35.0) e no IE (versão 11).

Você pode explorar isso usando o seguinte trecho:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <!--import css here-->
        <!--import js scripts here-->

        <script language="javascript">

            function bodyOnloadHandler() {
                console.log("body onload");
            }

            window.onload = function(e) {
                console.log("window loaded");
            };
        </script>
    </head>

    <body onload="bodyOnloadHandler()">

        Page contents go here.

    </body>
</html>

E você verá "janela carregada" (que vem em primeiro lugar) e "carga corporal" no console do Chrome. No entanto, você verá apenas "carga corporal" no Firefox e no IE. Se você executar " window.onload.toString()" nos consoles do IE & FF, verá:

"função onload (evento) {bodyOnloadHandler ()}"

o que significa que a atribuição "window.onload = function (e) ..." é substituída.

VincentZHANG
fonte
6

window.onloade onunloadsão atalhos para document.body.onloadedocument.body.onunload

document.onloade onloadmanipulador em todas as tags html parecem reservados, porém nunca acionados

' onload' no documento -> true

garaboncias
fonte
5

window.onload, no entanto, geralmente são a mesma coisa. Da mesma forma, body.onload se torna window.onload no IE.

AnthonyWJones
fonte
1

Window.onload é o padrão, no entanto - o navegador da Web no PS3 (baseado no Netfront) não suporta o objeto window, portanto você não pode usá-lo lá.

Gotofritz
fonte
0

Em resumo

  • windows.onloadnão é suportado pelo IE 6-8
  • document.onload não é suportado por nenhum navegador moderno (o evento nunca é acionado)

Kamil Kiełczewski
fonte