Recevoir une notification lorsque la page DOM a été chargée (mais avant window.onload)

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

  •  09-06-2019
  •  | 
  •  

Question

Je sais qu'il est possible de recevoir une notification lorsque le corps de la page est chargé (avant le chargement de toutes les images et des ressources tierces déclenchant l'événement window.onload ), mais chaque navigateur est différent. .

Existe-t-il un moyen sûr de le faire sur tous les navigateurs?

Jusqu'à présent, je connais:

  • DOMContentLoaded : sur Mozilla, Opera 9 et les derniers kits Web. Cela implique l'ajout d'un écouteur à l'événement:

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

  • Script différé : sous IE, vous pouvez émettre une balise SCRIPT avec un attribut @defer, qui ne sera chargée qu'après la fermeture de la balise BODY.

  • Polling : sur d'autres navigateurs, vous pouvez continuer à interroger, mais existe-t-il même une option standard à interroger ou devez-vous effectuer des tâches différentes sur chaque navigateur?

J'aimerais pouvoir utiliser le fichier document.write ou des fichiers externes.

Ceci peut être fait simplement via jQuery:

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

mais, j'écris une bibliothèque JS et je ne peux pas compter sur jQuery toujours là.

Était-ce utile?

La solution

Il n’existe pas de méthode multi-navigateurs permettant de vérifier si le DOM est prêt - c’est la raison pour laquelle des bibliothèques comme jQuery existent pour résumer les incohérences désagréables.

Mozilla, Opera et le WebKit moderne prennent en charge l'événement DOMContentLoaded. IE et Safari ont besoin de hacks bizarres comme faire défiler la fenêtre ou vérifier les feuilles de style. Les détails sanglants sont contenus dans la bindReady() fonction de jQuery.

Autres conseils

J'ai trouvé cette page, qui montre une solution compacte et autonome. Il semble fonctionner sur tous les navigateurs et explique comment:

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

Pour ce faire, YUI utilise trois tests: pour Firefox et pour le WebKit récent, un événement DOMContentLoaded est déclenché. Pour les anciens Safari, document.readyState a regardé jusqu'à ce qu'il devienne & "; Chargé &"; ou " compléter " ;. Pour IE, un HTML & Lt; P & Gt; La balise est créée et le & "; doScroll () &"; méthode appelée qui devrait sortir d'erreur si le DOM n'est pas prêt. La source de YAHOO.util.Event affiche du code spécifique à YUI. Rechercher & Quot; doScroll & Quot; dans le fichier Event.js.

L'utilisation d'une bibliothèque telle que jQuery vous évitera d'innombrables heures d'incohérences dans les navigateurs.

Dans ce cas avec jQuery, vous pouvez simplement

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

Si vous êtes curieux, vous pouvez jeter un coup d’œil à la source pour voir comment cela se passe, mais je ne pense pas que ce jour-là, personne ne devrait réinventer cette roue alors que le rédacteur de la bibliothèque a fait tout le travail pénible qui a été accompli. vous.

Prenez juste le morceau de code correspondant dans jQuery, John Resig a déjà couvert la plupart des bases sur ce problème dans jQuery.

Pourquoi pas ceci:

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

Si je comprends bien les choses, myInit sera exécuté dès que le navigateur l'aura affiché dans la page, ce qui constitue la dernière chose dans un corps.

La solution multijoueur sophistiquée que vous recherchez ... n'existe pas ... (imaginez le son d'une foule qui se dit "aahhhh ....").

DomContentLoaded est tout simplement votre meilleur atout. Vous avez toujours besoin de la polling technique pour IE-oldies.

  1. Essayez d'utiliser addEventListener;
  2. Si non disponible (IE évidemment), recherchez les cadres;
  3. S'il ne s'agit pas d'un cadre, faites défiler jusqu'à ce qu'aucune erreur ne soit renvoyée (interrogation);
  4. Si un cadre, utilisez l'événement IE document.onreadystatechange;
  5. Pour les autres navigateurs non compatibles, utilisez l'ancien événement document.onload.

J'ai trouvé l'exemple de code suivant sur javascript.info. que vous pouvez utiliser pour couvrir tous les navigateurs:

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

Cela fonctionne plutôt bien:

setTimeout(MyInitFunction, 0);

L’utilisation de setTimeout peut très bien fonctionner, bien qu’elle soit exécutée par le navigateur. Si vous passez à zéro comme délai d'attente, le navigateur s'exécutera lorsque les éléments & "; Réglés &";.

La bonne chose à propos de cela est que vous pouvez en avoir beaucoup, sans avoir à vous soucier de l'enchaînement des événements onLoad.

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

etc.

Ils seront tous exécutés une fois le chargement du document terminé ou, si vous en définissez un après le chargement du document, ils seront exécutés une fois le script exécuté.

L'ordre dans lequel ils sont exécutés n'est pas déterminé et peut changer d'un navigateur à l'autre. Vous ne pouvez donc pas compter sur myFunction l'exécution avant anotherFunction par exemple.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top