ホームページ >ウェブフロントエンド >jsチュートリアル >Javascript は DOMContentLoaded イベントのインスタンス_JavaScript スキルをカプセル化します

Javascript は DOMContentLoaded イベントのインスタンス_JavaScript スキルをカプセル化します

WBOY
WBOYオリジナル
2016-05-16 16:44:461291ブラウズ

私は最近 Javascript フレームワークを作成しており、DOMContentLoaded イベントをカプセル化したところです。少し興奮して、開発プロセス中に発生した原則と互換性の問題についてメモを取りました。それをあらゆる場所で探すことを忘れないようにしてください。 。

JS コードを記述するときは、通常、window.onload イベントを追加します。これは主に、DOM がロードされた後、getElementById、getElementsByTagName、およびその他のメソッドを使用して操作対象の DOM 要素を選択できるようにするためですが、window.load は待機するまで待機します。 DOM がロードされると、最終画像または iframe がロードされるまで、スクリプト、CSS、およびすべてのリソースがトリガーされません。多くの場合、Web ページには大量の大きな画像が含まれており、js を実行するには明らかに遅すぎます。最後の画像が読み込まれるまでは時間がかかり、多くの場合、手遅れになってしまいます。

多くの js フレームワークには、JQuery の $(document).ready() メソッドなどの document.ready 関数があり、DOM がロードされた直後に js コードを実行し、画像をゆっくりとロードできます。

document.ready のコアは DOMContentLoaded イベントです。Firefox、chrome、opera、safari、ie9 はすべてイベント バインディングに addEventListener('DOMContentLoaded',fn,false) を使用できますが、ie6 ~ 8 は DOMContentLoaded をサポートしていません。イベントが発生するため、ie6~8の互換処理が必要です。

情報によると、ie6~8 は document.onreadystatechange イベントを使用して document.readyState ステータスが complete に等しいかどうかを監視し、ページに iframe が埋め込まれているかどうかを判断できます。 ie6~8のdocument.readyStateはiframeが完了するまで待機します。このとき、iframeは時間がかかるものになります。しかし、テスト後、ページに iframe がなくても、readyState が complete に等しい場合、DOMContentLoaded イベントの代わりに onload イベントが実際にトリガーされることに驚きました。

幸いなことに、IE には独自の doScroll メソッドがあり、ページ DOM がロードされていない場合、doScroll メソッドが呼び出されたときにエラーが報告されます。それとは逆に、エラーが報告されなくなるまで doScroll が呼び出されるまでです。 、これはページ DOM がロードされたことを意味します。このメソッドは、画像と iframe のコンテンツがロードされているかどうかに関係なく有効です。

document.ready イベントに複数の js ファイルがバインドされている場合、ブラウザが繰り返しバインドするのを防ぎ、それらを順序立てて実行するために、イベント キュー メカニズムを導入して問題を解決できます。

上記は document.ready イベントの原理と互換性の問題です。 以下は、実行処理を理解しやすくするために、関数のカプセル化モードを使用しています。何か問題があります。アドバイスを歓迎します。

コードをコピー コードは次のとおりです:

//domReadyのイベントキューを保存
eventQueue = [];

//DOMがロードされているか判定
isReady = false;

/ /DOMReady がバインドされているかどうかを判断します
isBind = false;

/*Execute domReady()
*
*@param {function}
*@execute イベント ハンドラーをイベントキュー、バインド DOMContentLoaded
* DOM ロードが完了したら、すぐに実行
*@caller
*/
function domReady(fn){
if (isReady) {
fn .call(window);
}
else{
eventQueue.push(fn);
};

bindReady();
};

/*domReady イベント binding
*
*@param null
*@execute 最近のブラウザは、ie9 を含む addEvListener を通じて DOMContentLoaded をバインドします
ie6-8 は、doScroll *@caller domReady()
*/
function bindingReady(){
if (isReady) return;
if (isBind) return;
isBind = true;

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

/*doScroll は ie6-8 の DOM がロードされているかどうかを決定します
*
*@param null
*@execute doScroll は DOM がロードされているかどうかを決定します
*@caller bindingReady()
*/
function doScroll(){
try{
document.documentElement.doScroll('left');
}
catch(error ) {
return setTimeout(doScroll,20);
};
execFn();
};

/*実行イベントキュー
*
*@ param null
*@execute 実行キューでイベント ハンドラーをループします
*@caller bindingReady()
*/
function execFn(){
if (!isReady) {
isReady = true;
for (var i = 0; i eventQueue[i].call(window);
};
eventQueue = [];
};
};

//js ファイル 1
domReady(function(){
...
});
//js ファイル 2
domReady(function(){
...
});

//非同期でロードされた js である場合は、domReady メソッドをバインドしないでください。そうでない場合、関数はバインドされません。
//非同期でロードされた JS がダウンロードされる前に DOMContentLoaded がトリガーされたため、addEventListener は実行時にリッスンできなくなります

テスト ページ: 2 つの大きなイメージがロードされます。Onload では、JS を実行する前にイメージをロードする必要があります。DOMContentLoaded は、JS を実行する前に DOM がロードされるまで待つ必要があります。 firebug を開いて読み込みプロセスを表示できます。各テストの前に必ずブラウザーのキャッシュをクリアしてください。


声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。