最近、JavaScriptフレームワークを書いています。 DomContentLoadedイベントをカプセル化したばかりで、少し興奮していました。どこでも忘れないように、開発プロセス中に遭遇した原則と互換性の問題についてメモを取りました。
JSコードを記述するとき、通常はwindow.onloadイベントを追加します。主にgetelementbyid、getElementsBytagname、およびその他のメソッドを使用して、DOMのロード後に操作用にDOM要素を選択します。ただし、Window.loadは、DOM、スクリプト、CSSがロードされ、画像内のすべてのリソースがトリガーされるまで待機します。多くの場合、Webページにはより多くの写真があり、より大きくなっています。画像をロードするのに長い時間がかかります。また、JSを実行するには明らかに遅すぎます。これは、ユーザーエクスペリエンスにしばしば影響します。
多くのJSフレームワークには、jqueryの$(document).ready()メソッドなどのDocument.ready関数があります。これは、DOMのロード後すぐにjjsコードを実行できるため、画像をゆっくり読み込むことができます。
document.readyのコアは、domcontentloadedイベントです。 Firefox、Chrome、Opera、Safari、およびIE9+はすべて、イベントバインディングにAddEventListener( 'domcontentloaded'、fn、false)を使用できます。 IE6〜8はdomContentLoadedイベントをサポートしていないため、IE6〜8で互換性処理を実行する必要があります。
情報によれば、IE6〜8はdocument.onedystatechangeイベントを使用して、Document.readyStateステータスが完全に等しいかどうかを聞き、DOMがロードされたかどうかを判断します。 iframeがページに埋め込まれている場合、IE6〜8のDocument.readyStateは、IFRAMEのすべてのリソースが完全になる前にロードされるまで待機します。この時点で、iframeは時間のかかる主要なユーザーになります。しかし、テスト後、ページにiframeがない場合でも、ReadyStateが完了すると、domcontentloadedイベントの代わりにオンロードイベントが実際にトリガーされます。これは驚くべきことです。
幸いなことに、IEには一意のドスクロール方法があります。 Page DOMがロードされていない場合、DoScrollメソッドが呼び出されるとエラーが報告されます。逆に、誤差が報告されないまでドスクロールが間隔で呼び出される限り、ページDOMがロードされていることを意味します。この方法は、画像内のコンテンツとIFRAMEがロードされているかどうかに関係なく有効です。
複数のJSファイルがDocument.readyイベントにバインドされている場合、ブラウザが整然とした方法で繰り返しバインドして実行するのを防ぐために、問題を解決するためにイベントキューメカニズムを導入できます。
上記は、Document.readyイベントの原則と互換性の問題です。以下は、例コードの段落です。実行プロセスの理解を促進するために、実行プロセスは、関数カプセル化モードを使用してコメントに記述されます。不適切なものがある場合は、アドバイスをください。
コードコピーは次のとおりです。
// domreadyのイベントキューを保存します
eventqueue = [];
// DOMがロードされているかどうかを判断します
isready = false;
// domreadyが拘束されているかどうかを判断します
isbind = false;
/*domready()を実行する
*
*@param {function}
*@executeイベントハンドラーをイベントキューに押し込み、domcontentloadedにバインドします
* DOMロードが完了した場合は、すぐに実行します
*@Caller
*/
function domready(fn){
if(isready){
fn.call(window);
}
それ以外{
eventqueue.push(fn);
};
bindready();
};
/*DOMREADYイベントバインディング
*
*@param null
*@IE9+を含むAddEvListenerを介してDomContentLoadedをバインドする最新のブラウザを実行します
IE6-8は、doScrollを判断することによりDOMがロードされたかどうかを判断します
*@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は、IE6-8のDOMがロードされているかどうかを決定します。
*
*@param null
*@doscrollを実行すると、DOMが読み込まれているかどうかが判断されます
*@caller bindready()
*/
function doscroll(){
試す{
document.documentelement.doscroll( 'left');
}
catch(error){
return setimeout(doscroll、20);
};
execfn();
};
/*実行イベントキュー
*
*@param null
*@キューでループ実行イベントハンドラーを実行します
*@caller bindready()
*/
関数execfn(){
if(!isready){
isready = true;
for(var i = 0; i <eventqueue.length; i ++){
eventqueue [i] .call(window);
};
eventqueue = [];
};
};
// JSファイル1
domready(function(){
...
});
// JSファイル2
domready(function(){
...
});
//非同期にロードされている場合は、domreadyメソッドに結合しないでください。そうしないと、関数は実行されません。
//非同期ロードJSダウンロードの前に、domContentLoadedが起動され、実行時にAddEventListenerを聞くことができないため
テストページ:2つの大きな画像がロードされています。 JSを実行する前に、オンロードでは画像をロードする必要があります。 domContentLoadedは、JSを実行するためにDOMがロードされるまで待機する必要があります。 FireBugを開いて荷重プロセスを表示できます。各テストの前にブラウザキャッシュをクリーニングすることを忘れないでください。