Obtenir notification lorsque la page DOM a chargé (mais avant window.onload)

Je sais qu'il existe des façons d'être averti lorsque le corps de la page a été chargé (avant que toutes les images et les ressources tierces ne chargent qui déclenchent l'événement window.onload ), mais c'est différent pour chaque navigateur.

Existe-t-il un moyen définitif de le faire sur tous les navigateurs?

Jusqu'à présent, je sais:

Je voudrais pouvoir passer sans utiliser document.write ou fichiers externes.

Cela peut se faire simplement via jQuery:

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

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

Il n'existe pas de méthode de navigateur croisé pour vérifier quand le DOM est prêt. C'est pourquoi il existe des bibliothèques comme jQuery, pour aboutir à de petits bits d'incompatibilité.

Mozilla, Opera et WebKit modernes prennent en charge l'événement DOMContentLoaded . IE et Safari ont besoin de hacks étranges comme le défilement de la fenêtre ou la vérification des feuilles de style. Les détails bindReady() sont contenus dans la fonction bindReady() de jQuery.

J'ai trouvé cette page, qui montre une solution autonome compacte. Il semble fonctionner sur chaque navigateur et a une explication sur comment:

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

YUI utilise trois tests pour ce faire: pour Firefox et récemment WebKit, il y a un événement DOMContentLoaded qui est déclenché. Pour plus d'anciennes Safari, le document a été visualisé jusqu'à ce qu'il soit "chargé" ou "complet". Pour IE, une balise HTML <P> est créée et la méthode "doScroll ()" appelée erreur devrait être si le DOM n'est pas prêt. La source de YAHOO.util.Event montre le code spécifique YUI. Recherchez "doScroll" dans Event.js.

L'utilisation d'une bibliothèque comme jQuery vous sauvera d'innombrables heures d'incohérences des 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 fait, mais est ce jour et cet âge que je ne pense pas que quelqu'un devrait réinventer cette roue lorsque l'écrivain de la bibliothèque a accompli tout le travail pénible pour vous.

Il suffit de prendre le code pertinent de jQuery, John Resig a couvert la plupart des bases sur ce problème déjà dans jQuery.

Pourquoi pas ceci:

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

Si je comprends bien les choses, myInit va être exécuté dès que le navigateur l'a frappé dans la page, ce qui est la dernière chose dans un corps.

La solution de traverse transversale chic que vous cherchez … n'existe pas … (imaginez le son d'une grande foule disant 'aahhhh ….').

DomContentLoaded est simplement votre meilleur coup. Vous avez toujours besoin de la technique d' polling pour les old-IE.

  1. Essayez d'utiliser addEventListener;
  2. Si elle n'est pas disponible (IE évidemment), vérifiez les cadres;
  3. Si ce n'est pas un cadre, faites défiler jusqu'à ce que aucune erreur ne soit lancée (sondage);
  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 très bien:

 setTimeout(MyInitFunction, 0); 

L'utilisation de setTimeout peut fonctionner assez bien, bien que lorsque cela est exécuté dépend du navigateur. Si vous passez zéro comme timeout time, le navigateur s'exécutera lorsque les choses seront "réglées".

La bonne chose à ce sujet est que vous pouvez en avoir beaucoup, et que vous ne devez pas vous soucier de lier les événements de lancement.

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

etc.

Ils seront tous exécutés lorsque le document a fini de charger, ou si vous le configurez une fois que le document a été chargé, ils seront exécutés après l'exécution de votre script.

L'ordre dans lequel ils se sont déroulés n'est pas déterminé et peut changer entre les navigateurs. Vous ne pouvez donc pas compter sur myFunction être exécuté avant anotherFunction par exemple.