Ficando notificado quando a página do DOM tem carregado (mas antes de janela.onload)

StackOverflow https://stackoverflow.com/questions/65434

  •  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á.

Foi útil?

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:

http://www.kryogenix.org/days/2007/09/26/shortloaded

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.

  1. Tente usar addEventListener;
  2. Se não estiver disponível (ou seja, obviamente), de seleção para os quadros;
  3. Se não for uma armação, role até que nenhum erro é acionada (polling);
  4. Se um quadro, usar o IE evento documento.onreadystatechange;
  5. 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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top