Quero executar um pouco de javascript antes que toda a página seja carregada. Isso é possível? Ou o código começa a ser executado </html>
?
javascript
html
picknick
fonte
fonte
Respostas:
Não só você pode , mas você deve fazer um esforço especial para não fazê-lo se não quiser. :-)
Quando o navegador encontra uma
script
tag clássica ao analisar o HTML, ele para de analisar e passa para o interpretador JavaScript, que executa o script. O analisador não continua até que a execução do script seja concluída (porque o script pode fazerdocument.write
chamadas para a marcação de saída que o analisador deve manipular).Esse é o comportamento padrão, mas você tem algumas opções para atrasar a execução do script:
Use módulos JavaScript. Um
type="module"
script é adiado até que o HTML tenha sido totalmente analisado e o DOM inicial criado. Este não é o principal motivo para usar módulos, mas é um dos motivos:O código será obtido (se for separado) e analisado em paralelo com a análise HTML, mas não será executado até que a análise HTML seja concluída. (Se o código do módulo estiver embutido em vez de em seu próprio arquivo, ele também será adiado até que a análise de HTML seja concluída.)
Isso não estava disponível quando escrevi esta resposta pela primeira vez em 2010, mas aqui em 2020, todos os principais navegadores modernos suportam módulos nativamente, e se você precisar suportar navegadores mais antigos, pode usar bundlers como Webpack e Rollup.js.
Use o
defer
atributo em uma tag de script clássico:Tal como acontece com o módulo, o código
my-code.js
será obtido e analisado em paralelo com a análise HTML, mas não será executado até que a análise HTML seja concluída. Mas ,defer
não funciona com conteúdo de script embutido, apenas com arquivos externos referenciados viasrc
.Não acho que seja o que você quer, mas você pode usar o
async
atributo para dizer ao navegador para buscar o código JavaScript em paralelo com a análise de HTML, mas depois executá-lo o mais rápido possível, mesmo se a análise de HTML não estiver completa . Você pode colocá-lo em umatype="module"
tag ou usá-lo em vez dedefer
em umascript
tag clássica .Coloque a
script
tag no final do documento, antes da</body>
tag de fechamento :Dessa forma, mesmo que o código seja executado assim que for encontrado, todos os elementos definidos pelo HTML acima dele existem e estão prontos para serem usados.
Antigamente, isso causava um atraso adicional em alguns navegadores porque eles não começavam a buscar o código até que a
script
tag fosse encontrada, mas os navegadores modernos fazem a varredura adiante e começam a pré-busca. Ainda assim, esta é a terceira escolha neste ponto, ambos os módulos edefer
são opções melhores.A especificação tem um diagrama útil mostrando uma matéria-
script
tag,defer
,async
,type="module"
, etype="module" async
e o momento em que o código JavaScript é buscado e corrida:Aqui está um exemplo do comportamento padrão, uma
script
tag bruta :(Veja minha resposta aqui para detalhes sobre esse
NodeList
código.)Ao executá-lo, você verá "Parágrafo 1" em verde, mas "Parágrafo 2" em preto, porque o script foi executado em sincronia com a análise de HTML e, portanto, encontrou apenas o primeiro parágrafo, não o segundo.
Em contraste, aqui está um
type="module"
script:Observe como eles estão verdes agora; o código não foi executado até que a análise de HTML foi concluída. Isso também seria verdadeiro com um
defer
script
conteúdo externo (mas não com conteúdo embutido).(Não houve necessidade de
NodeList
verificar porque qualquer navegador moderno com suporte a módulos já estáforEach
ativadoNodeList
.)Neste mundo moderno, não há valor real para o
DOMContentLoaded
evento do recurso "pronto" que PrototypeJS, jQuery, ExtJS, Dojo e muitos outros forneciam (e ainda fornecem); apenas use módulos oudefer
. Mesmo no passado, não havia muitos motivos para usá-los (e muitas vezes eram usados incorretamente, segurando a apresentação da página enquanto toda a biblioteca jQuery era carregada porque oscript
estava no emhead
vez de depois do documento), algo que alguns desenvolvedores em O Google sinalizou no início. Isso também foi parte da razão para a recomendação da YUI de colocar scripts no final do diabody
, novamente.fonte
<body onload="doIt()>"
.load
evento acontece muito tarde no ciclo de carregamento da página, quase nunca é uma prática recomendada esperar para executar seu JavaScript até então. Mas sim, é uma opção. Eu revisei a resposta para 2020, aliás.document.addEventListener('DOMContentLoaded', function(){ //doyour stuff })
Você pode executar o código javascript a qualquer momento. O AFAIK é executado no momento em que o navegador atinge a tag <script> onde está. Mas você não pode acessar elementos que ainda não foram carregados.
Portanto, se você precisa de acesso aos elementos, deve esperar até que o DOM seja carregado (isso não significa que toda a página seja carregada, incluindo imagens e outras coisas. É apenas a estrutura do documento, que é carregada muito antes, então você geralmente ganha perceber um atraso), usando o
DOMContentLoaded
evento ou funções como$.ready
em jQuery.fonte