Ficando notificado quando a página do DOM tem carregado (mas antes de janela.onload)
-
09-06-2019 - |
Pergunta
Eu sei que existem algumas maneiras para que você seja notificado quando o corpo da página tem carregado (antes de todas as imagens e 3ª festa de carga dos recursos que aciona o janela.onload o evento), mas é diferente para cada navegador.
Há uma forma definitiva para fazer isso em todos os navegadores?
Até agora não sei de:
DOMContentLoaded :No Mozilla, Opera 9 e o mais novo WebKits.Isso envolve a adição de um ouvinte para o evento:
documento.addEventListener( "DOMContentLoaded", [função init], false );
Diferidos script:No IE, você pode emitir uma tag de SCRIPT com um @atributo defer, que vão confiável carregar somente após o fechamento da tag BODY.
Sondagem:Em outros navegadores, você pode manter a pesquisa, mas é que existe mesmo um padrão coisa para pesquisar, ou fazer o que você precisa fazer coisas diferentes em cada navegador?
Eu gostaria de ser capaz de ir sem o uso de documento.escrever ou arquivos externos.
Isso pode ser feito simplesmente através de jQuery:
$(document).ready(function() { ... })
mas, eu estou escrevendo um JS biblioteca e não pode contar com jQuery, sempre estar lá.
Solução
Não há cross-browser método para verificar quando o DOM estiver pronto -- é por isso que as bibliotecas como jQuery existir, para abstraem pouco desagradável bits de incompatibilidade.
A Mozilla, Opera, moderno e WebKit apoio a DOMContentLoaded
do evento.IE e Safari precisa estranho hacks como a rolagem da janela, ou a verificação de folhas de estilo.Os detalhes estão contidos no jQuery bindReady()
função.
Outras dicas
Eu encontrei esta página, que mostra um compacto, auto-contido solução.Parece que funciona em todos os navegadores e tem uma explicação sobre como:
YUI usa três testes para fazer isso:para o Firefox e recente do WebKit, há uma DOMContentLoaded evento que é disparado.Para mais antigos Safari o documento.readyState assisti até que ele se torna "carregado" ou "completa".Para o IE HTML <P> tag é criado e o "doScroll()" método chamado que deve erro se o DOM não está pronto.A origem YAHOO.util.Eventos mostra YUI-código específico.Procure por "doScroll" no Event.js.
Usando uma biblioteca como jQuery irá salvar-lhe horas incontáveis de navegadores inconsistências.
Neste caso com jQuery, você pode apenas
$(document).ready ( function () {
//your code here
});
Se você estiver curioso, você pode ter um olhar para a fonte para ver como ele é feito, mas é neste dia e idade, eu não acho que alguém deve ser reinventar esse roda quando a biblioteca do escritor ter feito tudo o doloroso trabalho para você.
Basta tomar a parte relevante do código do jQuery, John Resig tem coberto a maior parte das bases sobre esta questão, já em jQuery.
Por que não este:
<body>
<!-- various content -->
<script type="text/javascript">
<!--
myInit();
-->
</script>
</body>
Se eu entendi corretamente as coisas, myInit vai chegar executado assim que o navegador bateu na página, que é a última coisa em um corpo.
A fantasia crossbrowser solução que você está procurando....não existe...(imagine o som de uma grande multidão, dizendo: 'aahhhh....').
DomContentLoaded é simplesmente o seu melhor tiro.Você ainda terá a polling
técnica para o IE-oldies.
- Tente usar addEventListener;
- Se não estiver disponível (ou seja, obviamente), de seleção para os quadros;
- Se não for uma armação, role até que nenhum erro é acionada (polling);
- Se um quadro, usar o IE evento documento.onreadystatechange;
- Para outras não-solidária navegadores, o uso do documento antigo.evento onload.
Eu encontrei o seguinte exemplo de código na javascript.info o que você pode usar para cobrir todos os navegadores:
function bindReady(handler){
var called = false
function ready() {
if (called) return
called = true
handler()
}
if ( document.addEventListener ) { // native event
document.addEventListener( "DOMContentLoaded", ready, false )
} else if ( document.attachEvent ) { // IE
try {
var isFrame = window.frameElement != null
} catch(e) {}
// IE, the document is not inside a frame
if ( document.documentElement.doScroll && !isFrame ) {
function tryScroll(){
if (called) return
try {
document.documentElement.doScroll("left")
ready()
} catch(e) {
setTimeout(tryScroll, 10)
}
}
tryScroll()
}
// IE, the document is inside a frame
document.attachEvent("onreadystatechange", function(){
if ( document.readyState === "complete" ) {
ready()
}
})
}
// Old browsers
if (window.addEventListener)
window.addEventListener('load', ready, false)
else if (window.attachEvent)
window.attachEvent('onload', ready)
else {
var fn = window.onload // very old browser, copy old onload
window.onload = function() { // replace by new onload and call the old one
fn && fn()
ready()
}
}
}
Isso funciona muito bem:
setTimeout(MyInitFunction, 0);
Usando setTimeout pode funcionar muito bem, apesar de quando é executado é para o navegador.Se você passar de zero à medida que o tempo limite de tempo, o navegador irá executar quando as coisas são "resolvidas".
A coisa boa sobre isso é que você pode ter muitos deles, e não terá de se preocupar com o encadeamento de eventos onLoad.
setTimeout(myFunction, 0);
setTimeout(anotherFunction, 0);
setTimeout(function(){ doSomething ...}, 0);
etc.
Todos eles vão executar quando o documento tiver sido carregado, ou se você definir um backup depois que o documento é carregado, eles serão executados após o seu script terminar a execução.
A ordem de execução não é determinado, e pode alterar entre os navegadores.Então você não pode contar com myFunction
a ser executado antes de anotherFunction
por exemplo.