Maison  >  Article  >  interface Web  >  Javascript encapsule les compétences instance_javascript de l'événement DOMContentLoaded

Javascript encapsule les compétences instance_javascript de l'événement DOMContentLoaded

WBOY
WBOYoriginal
2016-05-16 16:44:461269parcourir

J'écris un framework Javascript récemment, et je viens d'encapsuler l'événement DOMContentLoaded. Avec un peu d'enthousiasme, j'ai pris des notes sur les principes et les problèmes de compatibilité rencontrés lors du processus de développement, pour ne pas oublier de le chercher partout. .

Lorsque nous écrivons du code js, nous ajoutons généralement l'événement window.onload, principalement pour qu'une fois le DOM chargé, nous puissions utiliser getElementById, getElementsByTagName et d'autres méthodes pour sélectionner les éléments DOM à utiliser, mais window.load attendra jusqu'à ce que le DOM est chargé. Les scripts, CSS et toutes les ressources de l'iframe ne seront déclenchés que lorsque l'image finale ou même l'iframe sera chargée. Plusieurs fois, les pages Web contiennent de nombreuses et grandes images. La dernière image, qui prend beaucoup de temps, est chargée avant d'exécuter js. Plusieurs fois, il est trop tard et cela affectera l'expérience utilisateur.

De nombreux frameworks js ont une fonction document.ready, telle que la méthode $(document).ready() de JQuery, qui peut exécuter le code js immédiatement après le chargement du DOM et laisser l'image se charger lentement.

Le cœur de document.ready est l'événement DOMContentLoaded. Firefox, Chrome, Opera, Safari et ie9 peuvent tous utiliser addEventListener('DOMContentLoaded',fn,false) pour la liaison d'événement, mais ie6~8 ne prend pas en charge DOMContentLoaded. événement, vous devez donc effectuer un traitement de compatibilité pour ie6 ~ 8.

Selon les informations, ie6~8 peut utiliser l'événement document.onreadystatechange pour vérifier si le statut document.readyState est égal à terminé afin de déterminer si le DOM a été chargé. S'il y a une iframe intégrée dans la page, le document.readyState de ie6~8 attendra que l'iframe ne soit terminée qu'une fois toutes les ressources chargées. À ce stade, l'iframe prend beaucoup de temps. Cependant, après le test, même s'il n'y a pas d'iframe dans la page, lorsque readyState est égal à complete, l'événement onload est en fait déclenché à la place de l'événement DOMContentLoaded. Cela me surprend.

Heureusement, IE dispose d'une méthode doScroll unique. Lorsque la page DOM n'a pas été chargée, une erreur sera signalée lorsque la méthode doScroll est appelée. Au contraire, tant que doScroll est appelé à intervalles jusqu'à ce qu'aucune erreur ne soit signalée. , cela signifie que la page DOM a été chargée , cette méthode est valable que le contenu de l'image et de l'iframe ait été chargé ou non.

S'il existe plusieurs fichiers js liés à l'événement document.ready, afin d'empêcher le navigateur de se lier à plusieurs reprises et de les exécuter de manière ordonnée, un mécanisme de file d'attente d'événements peut être introduit pour résoudre le problème.

Ce qui précède présente le principe et les problèmes de compatibilité de l'événement document.ready. Vous trouverez ci-dessous un exemple de code Afin de faciliter la compréhension du processus d'exécution, le mode d'encapsulation de la fonction est utilisé dans les commentaires. il y a quelque chose qui ne va pas, bienvenue Donnez des conseils.

Copier le code Le code est le suivant :

//Enregistrez la file d'attente des événements de domReady
eventQueue = [];

//Jugez si le DOM est chargé
isReady = false;

/ /Judge Si DOMReady est lié
isBind = false;

/*Execute domReady()
*
*@param {function}
*@execute Poussez le gestionnaire d'événements dans le file d'attente des événements et lie DOMContentLoaded
* Si le chargement du DOM est terminé, exécutez immédiatement
*@caller
*/
function domReady(fn){
if (isReady) {
fn .call(window);
}
else{
eventQueue.push(fn);
};

bindReady();
};

/*liaison d'événement domReady
*
*@param null
*@execute Les navigateurs modernes lient DOMContentLoaded via addEvListener, y compris ie9
ie6-8 détermine si le DOM est chargé en jugeant doScroll
*@caller domReady()
*/
function bindReady(){
if (isReady) return;
if (isBind) return;
isBind = true;

if (window.addEventListener) {
document.addEventListener('DOMContentLoaded',execFn,false);
}
else if (window.attachEvent) {
doScroll();
} ;
};

/*doScroll détermine si le DOM de ie6-8 est chargé
*
*@param null
*@execute doScroll détermine si le DOM est chargé
*@caller bindReady()
*/
function doScroll(){
try{
document.documentElement.doScroll('left');
}
catch(error ) {
return setTimeout(doScroll,20);
};
execFn();
};

/*File d'attente des événements d'exécution
*
*@ param null
*@execute Boucle le gestionnaire d'événements dans la file d'attente d'exécution
*@caller bindReady()
*/
function execFn(){
if (!isReady) {
isReady = true;
for (var i = 0; i < eventQueue.length; i ) {
eventQueue[i].call(window);
};
eventQueue = [];
};
};

//fichier js 1
domReady(function(){
...
});
//fichier js 2
domReady(function(){
...
});

//Remarque, s'il s'agit d'un js chargé de manière asynchrone, ne liez pas la méthode domReady, sinon la fonction ne sera pas être exécuté,
//Parce que DOMContentLoaded a été déclenché avant le téléchargement du js chargé de manière asynchrone, addEventListener ne peut plus écouter lorsqu'il est exécuté

Page de test : deux grandes images sont chargées. Onload nécessite que les images soient chargées avant que js puisse être exécuté. DOMContentLoaded n'a besoin que d'attendre que le DOM soit chargé avant d'exécuter js. Vous pouvez ouvrir Firebug pour visualiser le processus de chargement. N'oubliez pas de vider le cache du navigateur avant chaque test.

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn