W3docs

Eventos do Ciclo de Vida da Página em JavaScript

Aprenda os eventos do ciclo de vida da página em JavaScript: DOMContentLoaded, load, beforeunload e unload — quando cada um dispara e as alternativas modernas.

Cada página que um navegador abre passa por uma sequência previsível de etapas: o HTML é analisado, recursos externos são baixados, o usuário interage e, por fim, a página é encerrada. O JavaScript expõe essa sequência por meio de quatro eventos do ciclo de vida da páginaDOMContentLoaded, load, beforeunload e unload. Saber exatamente quando cada um dispara permite executar código de inicialização no momento mais cedo seguro, adiar trabalho custoso até que tudo esteja pronto e proteger o usuário de perder dados não salvos.

Este guia abrange o significado de cada evento, a ordem em que disparam, os erros comuns e as substituições modernas para os eventos que os navegadores agora desaconselham. Todos os exemplos abaixo são executáveis — cole-os em um arquivo HTML ou abra-os no editor integrado.

O ciclo de vida da página em resumo

Os eventos disparam em uma ordem fixa. Os dois primeiros ocorrem quando a página está sendo carregada; os dois últimos ocorrem quando o usuário sai:

EventoAlvoQuando disparaUso típico
DOMContentLoadeddocumentO HTML foi completamente analisado; scripts executaram; imagens/estilos podem ainda estar carregandoInicializar a interface, adicionar listeners, consultar o DOM
loadwindowA página e todos os sub-recursos (imagens, folhas de estilo, iframes) terminaramLer dimensões de imagens, executar código que precisa de tudo presente
beforeunloadwindowO usuário está prestes a navegar para outra páginaAvisar sobre alterações não salvas
unloadwindowA página está sendo encerrada (obsoleto)Limpeza legada / análises

Uma conclusão importante: DOMContentLoaded é o evento que você vai querer na maioria das vezes. Ele dispara muito antes do load, portanto anexar seu código a ele torna a página interativa mais cedo.

Aprofundamento no Evento DOMContentLoaded

O evento DOMContentLoaded dispara assim que o documento HTML foi completamente analisado, o que normalmente ocorre muito antes que imagens, folhas de estilo e outros recursos externos sejam carregados. Nesse momento, a árvore DOM está completa, portanto document.getElementById, querySelector e similares encontrarão todos os elementos escritos no HTML.

Como ele não espera por imagens ou CSS, você deve usar DOMContentLoaded sempre que seu script precisar apenas da estrutura DOM — o que é o caso mais comum.

Como scripts afetam o DOMContentLoaded

O navegador pausa a análise do HTML sempre que encontra uma tag <script> comum, executa o script e só então continua. Isso significa que DOMContentLoaded aguarda scripts síncronos. Há duas nuances importantes:

  • <script async> é executado assim que é baixado e não bloqueia DOMContentLoaded.
  • <script defer> é executado após o documento ser analisado, mas antes do disparo de DOMContentLoaded, na ordem do documento.

Se você controla o tempo de execução dos scripts com esses atributos, consulte scripts: async, defer para uma visão completa.

Verificando o estado com document.readyState

Se seu código pode ser executado depois que o DOM já foi analisado (por exemplo, um script adicionado dinamicamente), o listener nunca dispararia porque o evento já ocorreu. Proteja-se com document.readyState:

function onReady() {
  console.log('DOM is ready, current state:', document.readyState);
}

if (document.readyState === 'loading') {
  // Still parsing — wait for the event.
  document.addEventListener('DOMContentLoaded', onReady);
} else {
  // 'interactive' or 'complete' — DOM is already ready.
  onReady();
}

readyState percorre três valores: "loading" enquanto analisa, "interactive" assim que o DOM está pronto (é quando DOMContentLoaded dispara) e "complete" assim que tudo, incluindo recursos, foi carregado (é quando load dispara).

Exemplo Interativo: DOMContentLoaded em Ação

Para ver DOMContentLoaded em ação, o exemplo a seguir atualiza o conteúdo de um elemento div assim que o documento HTML é completamente analisado, mas antes de a página inteira ser completamente carregada.

<!DOCTYPE html>
<html lang="en">
<head>
    <title>DOMContentLoaded Example</title>
</head>
<body>
    <div id="output">Waiting for DOM...</div>
    <script>
        document.addEventListener('DOMContentLoaded', function() {
            document.getElementById('output').innerHTML = 'DOM fully loaded and parsed!'
        });
    </script>
</body>
</html>

Este exemplo pode ser colado em qualquer arquivo HTML e visualizado em um navegador para observar com que rapidez DOMContentLoaded dispara em comparação com o carregamento completo da página.

Explorando o Evento load

O evento load é essencial para operações que exigem que toda a página seja completamente carregada, incluindo todos os recursos dependentes, como imagens e folhas de estilo. Quando load dispara, cada imagem tem suas dimensões reais, as fontes estão aplicadas e os iframes estão carregados — portanto, este é o lugar certo para código que mede a página renderizada.

A desvantagem é o tempo: uma única imagem grande ou um widget de terceiros lento atrasa load para a página inteira. É por isso que você deve reservar load para trabalho que depende genuinamente de recursos e manter a inicialização comum em DOMContentLoaded. Para carregamento e tratamento de erros de recursos individuais (em vez de toda a página), consulte carregamento de recursos: onload e onerror.

Exemplo Interativo: Demonstrando o Evento load

Aqui, criamos um exemplo em que uma mensagem é exibida somente após tudo na página estar completamente carregado. Como você pode ver, o evento DOMContentLoaded sempre ocorre antes do evento load.

<!DOCTYPE html>
<html lang="en">
<head>
  <title>Load Event Example</title>
</head>
<body>
  <div>You see first triggered event on top of the other.</div>
  <script>
    window.addEventListener('load', function() {
      const newDiv = document.createElement("div");
      newDiv.innerHTML = 'loaded event happened!'
      document.body.append(newDiv);
    });
    window.addEventListener('DOMContentLoaded', function() {
      const newDiv = document.createElement("div");
      newDiv.innerHTML = 'DOMContentLoaded event happened!'
      document.body.append(newDiv);
    });
  </script>
</body>
</html>

Copie e teste este código em seu próprio ambiente HTML para ver a diferença de tempo entre DOMContentLoaded e load.

Usando o Evento beforeunload

O evento beforeunload é extremamente útil para evitar perda de dados, alertando os usuários antes de navegarem para fora de uma página que pode ter alterações não salvas. Quando um handler define event.returnValue, o navegador exibe um diálogo de confirmação genérico ("Sair do site? As alterações feitas podem não ser salvas").

Algumas regras que os navegadores agora aplicam, importantes de conhecer antes de depender deste evento:

  • A mensagem personalizada é ignorada. Para evitar spam, os navegadores exibem seu próprio texto independentemente do string que você atribuir. Definir returnValue para qualquer valor não vazio (ou chamar event.preventDefault()) é suficiente para acionar o prompt.
  • O diálogo só aparece se o usuário interagiu com a página (clicou, digitou, etc.). Uma página que o usuário nunca tocou não pode bloquear a navegação.
  • Registre o handler somente quando houver alterações não salvas e remova-o assim que os dados forem salvos. Um handler permanente de beforeunload irrita os usuários e pode prejudicar o desempenho do cache de navegação para frente e para trás.

Um padrão mais robusto adiciona e remove o listener com base em um sinalizador de alterações:

let isDirty = false;

function beforeUnloadHandler(event) {
  event.preventDefault();
  // Required for some browsers to show the dialog.
  event.returnValue = '';
}

function markDirty() {
  if (!isDirty) {
    isDirty = true;
    window.addEventListener('beforeunload', beforeUnloadHandler);
  }
}

function markSaved() {
  isDirty = false;
  window.removeEventListener('beforeunload', beforeUnloadHandler);
}

Exemplo Interativo: Implementando Confirmação com beforeunload

Este exemplo exibe um diálogo de confirmação ao usuário quando ele tenta sair da página, ajudando a evitar perda acidental de dados.

<!DOCTYPE html>
<html lang="en">
<head>
    <title>beforeunload Example</title>
</head>
<body>
    <p>Now if you want to exit this page, a confirmation alert will be shown as a result of the <code>beforeunload</code> event.</p>
    <script>
        window.addEventListener('beforeunload', function(event) {
            event.returnValue = '';
        });
    </script>
</body>
</html>

Teste este código entrando na página "tente você mesmo" e então tentando navegar para outra página.

Usando o Evento unload

Aviso

The unload event is deprecated and you won't be able to use it in most modern browsers. It is also considered a bad practice. Therefore this part is only for better information about legacy codes.

Embora seja menos usado devido às restrições dos navegadores modernos e ao surgimento de aplicações de página única, o evento unload historicamente era executado quando uma página estava sendo encerrada — útil para limpar recursos ou enviar um ping final de análise. O problema é que unload (e beforeunload) impede que o navegador armazene a página no cache de navegação para frente e para trás (bfcache), o que torna a navegação pelo botão Voltar mais lenta para todos.

Alternativas modernas: visibilitychange e pagehide

Em vez de unload, ouça visibilitychange e trate a transição para "hidden" como o último momento confiável para persistir o estado. Isso dispara de forma consistente no desktop e mobile, inclusive quando o usuário troca de aba ou fecha o aplicativo:

document.addEventListener('visibilitychange', () => {
  if (document.visibilityState === 'hidden') {
    // Last reliable point to save state.
    console.log('Page hidden — flush analytics / save draft here');
  }
});

Para enviar dados ao sair, use navigator.sendBeacon(), que enfileira uma requisição que sobrevive ao fechamento da página:

function sendStats(data) {
  navigator.sendBeacon('/log', JSON.stringify(data));
}

Exemplo Interativo: Usando o Evento unload

Este código exibe uma mensagem de alerta quando a página está sendo encerrada. Está obsoleto conforme mencionado e não funciona na maioria dos navegadores modernos — prefira visibilitychange acima.

<!DOCTYPE html>
<html lang="en">
<head>
    <title>unload Example</title>
</head>
<body>
    <script>
        window.addEventListener('unload', function(event) {
            alert('Page is unloading...');
            // Perform cleanup tasks or analytics here
        });
    </script>
</body>
</html>

Conclusão

Cada um desses eventos serve a uma fase específica no ciclo de vida de uma página, desde o carregamento inicial até o encerramento final. O guia prático é simples:

  • Execute a maior parte da inicialização em DOMContentLoaded — dispara primeiro e o DOM está pronto.
  • Use load apenas quando depender de imagens, fontes ou outros sub-recursos completamente presentes.
  • Use beforeunload para proteger alterações não salvas e adicione o listener somente enquanto há dados não salvos.
  • Evite unload; prefira visibilitychange com navigator.sendBeacon().

Para aprofundar-se, explore estes capítulos relacionados:

Prática

Prática
O que o evento 'beforeunload' faz no exemplo HTML fornecido?
O que o evento 'beforeunload' faz no exemplo HTML fornecido?
Was this page helpful?