Ricevere una notifica quando il DOM della pagina viene caricato (ma prima di window.onload)

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

  •  09-06-2019
  •  | 
  •  

Domanda

So che ci sono alcuni modi per ricevere una notifica quando il corpo della pagina viene caricato (prima che tutte le immagini e le risorse di terze parti vengano caricate, il che attiva il finestra.onload evento), ma è diverso per ogni browser.

Esiste un modo definitivo per farlo su tutti i browser?

Finora so di:

  • DOMContentLoaded :Su Mozilla, Opera 9 e i WebKit più recenti.Ciò comporta l'aggiunta di un ascoltatore all'evento:

    document.addEventListener( "DOMContentLoaded", [funzione init], false );

  • Copione differito:Su IE, puoi emettere un tag SCRIPT con un attributo @defer, che verrà caricato in modo affidabile solo dopo la chiusura del tag BODY.

  • Sondaggio:Su altri browser è possibile continuare a eseguire il polling, ma esiste un elemento standard per cui eseguire il polling o è necessario eseguire operazioni diverse su ciascun browser?

Mi piacerebbe poter fare a meno dell'utilizzo di document.write o di file esterni.

Questo può essere fatto semplicemente tramite jQuery:

$(document).ready(function() { ... })

ma sto scrivendo una libreria JS e non posso contare sul fatto che jQuery sia sempre presente.

È stato utile?

Soluzione

Non esiste un metodo cross-browser per verificare quando il DOM è pronto: ecco perché esistono librerie come jQuery, per eliminare piccoli fastidiosi frammenti di incompatibilità.

Mozilla, Opera e il moderno WebKit supportano il formato DOMContentLoaded evento.IE e Safari hanno bisogno di strani trucchi come scorrere la finestra o controllare i fogli di stile.I dettagli cruenti sono contenuti in jQuery bindReady() funzione.

Altri suggerimenti

Ho trovato questa pagina, che mostra una soluzione compatta e autonoma.Sembra funzionare su ogni browser e ha una spiegazione su come:

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

YUI utilizza tre test per fare questo:per Firefox e il recente WebKit viene attivato un evento DOMContentLoaded.Per i Safari più vecchi, document.readyState veniva osservato finché non veniva "caricato" o "completo".Per IE viene creato un tag HTML <P> e viene chiamato il metodo "doScroll()" che dovrebbe generare un errore se il DOM non è pronto.La fonte per YAHOO.util.Evento mostra il codice specifico YUI.Cerca "doScroll" in Event.js.

L'utilizzo di una libreria come jQuery ti farà risparmiare innumerevoli ore di incoerenze dei browser.

In questo caso con jQuery puoi semplicemente

$(document).ready ( function () {
    //your code here
});

Se sei curioso puoi dare un'occhiata alla fonte per vedere come è fatto, ma al giorno d'oggi non penso che nessuno dovrebbe reinventare questa ruota quando lo scrittore della biblioteca ha fatto tutto il lavoro doloroso per te.

Basta prendere la parte di codice pertinente da jQuery, John Resig ha trattato la maggior parte delle basi su questo problema già in jQuery.

Perché non questo:

<body>  
  <!-- various content -->  
  <script type="text/javascript">  
  <!--  
    myInit();  
  -->
  </script>  
</body>  

Se ho capito bene le cose, myInit verrà eseguito non appena il browser lo raggiunge nella pagina, che è l'ultima cosa in un corpo.

La fantastica soluzione crossbrowser che stai cercando...non esiste...(immagina il suono di una grande folla che dice 'aahhhh....').

DomContentLoaded è semplicemente il tuo scatto migliore.Hai ancora bisogno del polling tecnica per IE-oldies.

  1. Prova a utilizzare addEventListener;
  2. Se non disponibile (IE ovviamente), controlla i frame;
  3. Se non è un frame, scorrere finché non viene generato alcun errore (polling);
  4. Se si tratta di un frame, utilizza l'evento IE document.onreadystatechange;
  5. Per altri browser non supportati, utilizzare il vecchio evento document.onload.

Ho trovato il seguente esempio di codice su javascript.info che puoi utilizzare per coprire tutti i browser:

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()
        }
    }
}

Funziona abbastanza bene:

setTimeout(MyInitFunction, 0);

L'uso di setTimeout può funzionare abbastanza bene, anche se il momento in cui viene eseguito dipende dal browser.Se si passa zero come tempo di timeout, il browser verrà eseguito quando le cose saranno "sistemate".

La cosa buona è che puoi averne molti e non devi preoccuparti di concatenare eventi onLoad.

setTimeout(myFunction, 0);
setTimeout(anotherFunction, 0);
setTimeout(function(){ doSomething ...}, 0);

eccetera.

Verranno tutti eseguiti al termine del caricamento del documento o, se ne imposti uno dopo il caricamento del documento, verranno eseguiti al termine dell'esecuzione dello script.

L'ordine in cui vengono eseguiti non è determinato e può cambiare da un browser all'altro.Quindi non puoi contare myFunction essere eseguito prima anotherFunction Per esempio.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top