O ciclo de vida de uma página HTML tem três eventos importantes:
-
DOMContentLoaded
– o navegador totalmente carregou HTML e a árvore DOM foi construída, mas os recursos externos como imagens<img>
e folhas de estilo podem ainda não ter sido carregados. -
load
– não apenas o HTML é carregado, mas também todos os recursos externos: imagens, estilos etc. -
beforeunload/unload
– o o usuário está saindo da página.
Cada evento pode ser útil:
-
DOMContentLoaded
evento – DOM está pronto , para que o manipulador possa pesquisar nós DOM, inicializar a interface. -
load
evento – recursos externos são carregados, portanto, estilos são aplicados, tamanhos de imagem são conhecidos etc. -
beforeunload
evento – o usuário está saindo: podemos verificar se o usuário salvou as alterações e perguntar se ele realmente deseja sair. - – o usuário quase saiu, mas ainda podemos iniciar algumas operações, como o envio de estatísticas.
Vamos explorar os detalhes desses eventos.
DOMContentLoaded
O evento DOMContentLoaded
acontece no objeto document
.
Nós deve usar addEventListener
para capturá-lo:
Por exemplo:
No exemplo, o manipulador DOMContentLoaded
é executado quando o documento é carregado, para que possa ver todos os elementos, incluindo <img>
abaixo.
Mas não espera a imagem carregar. Portanto, alert
mostra tamanhos zero.
À primeira vista, o evento DOMContentLoaded
é muito simples. A árvore DOM está pronta – aqui está o evento. No entanto, existem algumas peculiaridades.
DOMContentLoaded e scripts
Quando o navegador processa um documento HTML e encontra uma tag <script>
, precisa ser executado antes de continuar criando o DOM. Isso é uma precaução, pois os scripts podem querer modificar o DOM e até mesmo document.write
nele, então DOMContentLoaded
tem que esperar.
Portanto, DOMContentLoaded definitivamente acontece após esses scripts:
No exemplo acima, vemos primeiro “Biblioteca carregada …” e depois “DOM pronto!” (todos os scripts são executados).
Existem duas exceções a esta regra:
- Scripts com o atributo
async
, que abordaremos um pouco mais tarde, não bloqueiamDOMContentLoaded
. - Scripts que são gerados dinamicamente com
document.createElement("script")
e depois adicionados à página da web também não bloqueiam este evento.
DOMContentLoaded e estilos
As folhas de estilo externas não afetam o DOM, então DOMContentLoaded
não espera por elas.
Mas há uma armadilha. Se tivermos um script após o estilo, então esse script deve esperar até que a folha de estilo carregue:
A razão para isso é que o script pode desejar obter coordenadas e outras propriedades de elementos dependentes de estilo, como em o exemplo acima. Naturalmente, ele precisa esperar que os estilos carreguem.
Enquanto DOMContentLoaded
espera pelos scripts, agora espera pelos estilos antes deles também.
Preenchimento automático do navegador integrado
Formulários de preenchimento automático do Firefox, Chrome e Opera em DOMContentLoaded
.
Por exemplo, se a página tiver um formulário com login e senha, e o navegador lembrou dos valores, então em DOMContentLoaded
ele pode tentar preenchê-los automaticamente (se aprovado pelo usuário).
Então, se DOMContentLoaded
é adiado por scripts de carregamento longo, então o preenchimento automático também aguarda. Você provavelmente viu isso em alguns sites (se usar o preenchimento automático do navegador) – os campos de login / senha não são preenchidos automaticamente imediatamente, mas há um atraso até que a página carregue totalmente. Na verdade, esse é o atraso até o evento DOMContentLoaded
.
window.onload
O load
evento no objeto window
dispara quando a página inteira é carregada, incluindo estilos, imagens e outros recursos. Este evento está disponível por meio da propriedade onload
.
O exemplo abaixo mostra corretamente os tamanhos das imagens, porque window.onload
espera por todas as imagens:
window.onunload
Quando um visitante sai da página, o unload
evento dispara em window
. Podemos fazer algo lá que não envolva atrasos, como fechar janelas pop-up relacionadas.
A exceção notável é o envio de análises.
Digamos que coletamos dados sobre como a página está usado: cliques do mouse, rola, áreas de página visualizadas e assim por diante.
Naturalmente, o evento unload
é quando o usuário nos deixa, e nós gostaríamos de salve os dados em nosso servidor.
Ele envia os dados em background.A transição para outra página não é atrasada: o navegador sai da página, mas ainda executa sendBeacon
.
Veja como usá-lo:
- A solicitação é enviada como POST.
- Podemos enviar não apenas uma string, mas também formulários e outros formatos, conforme descrito no capítulo Buscar, mas geralmente é um objeto stringificado.
- Os dados são limitados a 64 kb.
Quando a sendBeacon
solicitação for concluída, o navegador provavelmente já saiu do documento, então não há como obter a resposta do servidor (que geralmente está vazia para análise).
Há também um sinalizador keepalive
para fazer essas solicitações “após a página esquerda” no método fetch para solicitações de rede genéricas. Você pode encontrar mais informações no capítulo Fetch API.
Se quisermos cancelar a transição para outra página, não podemos fazer isso aqui. Mas podemos usar outra evento – onbeforeunload
.
window.onbeforeunload
Se um visitante iniciou a navegação aw ay da página ou tenta fechar a janela, o beforeunload
manipulador pede uma confirmação adicional.
Se cancelarmos o evento, o navegador pode perguntar ao visitante se eles têm certeza.
Você pode tentar executando este código e recarregando a página:
Por razões históricas, retornar uma string não vazia também conta como cancelamento o evento. Há algum tempo, os navegadores costumavam mostrá-lo como uma mensagem, mas, como diz a especificação moderna, não deveriam.
Aqui está um exemplo:
O comportamento foi alterado , porque alguns webmasters abusaram desse manipulador de eventos, mostrando mensagens enganosas e irritantes. Portanto, no momento, navegadores antigos ainda podem exibi-lo como uma mensagem, mas fora isso – não há como personalizar a mensagem exibida para o usuário.
readyState
O que acontece se definirmos o manipulador DOMContentLoaded
após o documento ser carregado?
Naturalmente, ele nunca é executado.
Há casos em que não temos certeza se o o documento está pronto ou não. Gostaríamos que nossa função fosse executada quando o DOM for carregado, seja agora ou mais tarde.
A propriedade document.readyState
nos informa sobre o estado de carregamento atual.
Existem 3 valores possíveis:
-
"loading"
– o documento está carregando. -
"interactive"
– o documento foi totalmente lido. -
"complete"
– o documento foi totalmente lido e todos os recursos (como imagens) foram carregados também.
Portanto, podemos verificar document.readyState
e configurar um manipulador ou executar o código imediatamente se estiver pronto.
Há também o evento readystatechange
que dispara quando o estado muda, então podemos imprimir todos esses estados assim:
O readystatechange
event é uma mecânica alternativa de rastreamento do estado de carregamento do documento, apareceu há muito tempo. Hoje em dia, raramente é usado.
Vamos ver o fluxo de eventos completo para ver se é completo.
Aqui está um documento com <iframe>
, <img>
e manipuladores que registram eventos:
O exemplo de trabalho está na sandbox.
A saída típica:
O os números entre colchetes indicam o tempo aproximado de quando isso acontece. Eventos rotulados com o mesmo dígito acontecem aproximadamente ao mesmo tempo (± alguns ms).
-
document.readyState
torna-seinteractive
imediatamente antes deDOMContentLoaded
. Na verdade, essas duas coisas têm o mesmo significado. -
document.readyState
se tornacomplete
quando todos os recursos (iframe
eimg
) são carregados. Aqui podemos ver que isso acontece quase ao mesmo tempo queimg.onload
(img
é o último recurso) ewindow.onload
. Mudar para o estadocomplete
significa o mesmo quewindow.onload
. A diferença é quewindow.onload
sempre funciona depois de todos os outrosload
manipuladores.
Resumo
Eventos de carregamento da página:
- O
DOMContentLoaded
dispara o evento emdocument
quando o DOM é pronto. Podemos aplicar JavaScript a elementos neste estágio.- Script como
<script>https://javascript.info/...</script>
ou<script src="https://javascript.info/..."></script>
bloqueia DOMContentLoaded, o navegador espera para que eles executem. - Imagens e outros recursos também podem continuar a carregar.
- Script como
- O
load
evento emwindow
dispara quando a página e todos os recursos são carregados. Raramente o usamos, porque geralmente não há necessidade de esperar tanto tempo. - O evento
beforeunload
emwindow
é acionado quando o usuário deseja sair da página. Se cancelarmos o evento, o navegador perguntará se o usuário realmente deseja sair (por exemplo, temos alterações não salvas). - O evento
unload
emwindow
dispara quando o usuário finalmente está saindo, no manipulador podemos apenas fazer coisas simples que não envolvem atrasos ou perguntas a um usuário. Por causa dessa limitação, raramente é usado. Podemos enviar uma solicitação de rede comnavigator.sendBeacon
. -
document.readyState
é o estado atual do documento, as alterações podem ser rastreado no eventoreadystatechange
:-
loading
– o documento está carregando. -
interactive
– o documento é analisado, acontece quase ao mesmo tempo queDOMContentLoaded
, mas antes disso. -
complete
– o documento e os recursos são carregados, acontece quase ao mesmo tempo quewindow.onload
, mas antes disso.
-