ホームページ >ウェブフロントエンド >jsチュートリアル >一部の主流の JS フレームワークにおける DOMReady イベントの実装の概要

一部の主流の JS フレームワークにおける DOMReady イベントの実装の概要

WBOY
WBOYオリジナル
2016-05-16 18:10:56992ブラウズ

より一般的に使用されるのは window の onload イベントであることが判明しました。このイベントの実際の効果は次のとおりです。このイベントは、ページ解析/DOM ツリーの確立が完了し、画像やスクリプトなどのすべてのリソースがダウンロードされた後にトリガーされます。 、スタイルシート、さらには iframe も完成します。これは多くの実用的なアプリケーションにとっては少し「遅すぎる」ものであり、ユーザー エクスペリエンスに影響を与えます。この問題を解決するために、DOMContentLoaded メソッドが ff に追加されました。このメソッドは、onload と比較して、他のリソースがロードされるのを待たずに、ページの DOM コンテンツがロードされた後にトリガーされます。 Webkit エンジンもバージョン 525 からこのイベントを導入し (Webkit nightly 1/2008:525)、Opera にもこのメソッドが含まれています。今のところ、主流の IE にはまだこれを追加する予定はありません。 IE では利用できませんが、常に解決策はあります。以下は、このイベントに関連するいくつかの主要な主流フレームワークの互換バージョン実装計画の比較です。
プロトタイプ
jQeury
。 Moontools
dojo
yui
ext
1. プロトタイプ
実装コード

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

(function() {
/* DOMContentLoaded イベントのサポートは、Dan Webb 氏、
Matthias Miller 氏、ディーン・エドワーズとジョン・レジグ。 */
var timer;
function fireContentLoadedEvent() {
if (timer) window.clearInterval(timer); document.fire("dom :loaded");
document.loaded = true;
if (document.addEventListener) {
if (Prototype.Browser.WebKit) {
タイマー= window.setInterval(function () {
if (/loaded|complete/.test(document.readyState))
fireContentLoadedEvent();
},
Event.observe(window); , "load", fireContentLoadedEvent );
} else {
document.addEventListener("DOMContentLoaded",
fireContentLoadedEvent, false);
document.write( "<" "script id=__onDOMContentLoaded defer src=//:>");
$("__onDOMContentLoaded").onreadystatechange = function() {
if (this.readyState = = "完了") {
this.onreadystatechange = null;
}
};


実装のアイデアは次のとおりです:
WebKit の場合、ドキュメントの readState 属性をポーリングします。この属性の値がロードされているか完了している場合、安全のために DOMContentLoaded イベントがトリガーされます。 window.onloadにイベントを登録します。
FFの場合はDOMContentLoadedイベントを直接登録します。
IEの場合はdocument.writeを使ってページにscript要素を追加し、最後にスクリプトの読み込み完了をDOMContentLoadedイベントとしてトリガーします。
この実装には主に 2 つの問題があります。まず、document.write でスクリプトを記述し、defer を設定する方法は、ページに iframe が含まれている場合にトリガーする前に iframe 内のコンテンツが読み込まれるまで待機します。これは onload とは異なります。大きな違いはありません。第 2 に、Webkit は 525 以降のバージョンで DOMContentLoaded メソッドを導入したため、これらのバージョンではポーリングを実装する必要がなく、最適化できます。

2. jQuery





コードをコピーします

コードは次のとおりです:
function bindingReady(){ if (readyBound ) return; readyBound = true; // Mozilla、Opera、および Webkit nightlies は現在このイベントをサポートしています if ( document.addEventListener ) { / / 便利なイベント コールバックを使用します
document.addEventListener( "DOMContentLoaded", function(){
document.removeEventListener( "DOMContentLoaded", argument.callee, false );
jQuery.ready() ;
}, false );
// IE イベント モデルが使用されている場合
} else if ( document.attachEvent ) {
// onload 前に確実に起動する、
// 遅いかもしれないiframe でも安全です
document.attachEvent("onreadystatechange", function(){
if ( document.readyState === "complete" ) {
document.detachEvent( "onreadystatechange", argument.callee ) ;
jQuery.ready();
}
});
// iframe ではない場合
// ドキュメントの準備ができているかどうかを継続的に確認します
if ( document.documentElement .doScroll && typeof window.frameElement === "unknown" ) (function(){
if ( jQuery.isReady ) return;
try {
// IE を使用する場合は、 Diego Perini によるトリック
// http://javascript.nwbox.com/IEContentLoaded/
document.documentElement.doScroll("left");
} catch( error ) {
setTimeout( argument .callee, 0 );
return;
}
// 待機中の関数
})(); / window.onload へのフォールバック。常に機能します。
jQuery.event.add( window, "load", jQuery.ready );


実装のアイデアは次のとおりです。
Webkit と Firefox を同等に扱い、両方とも DOMContentLoaded イベントを直接登録します。ただし、Webkit はバージョン 525 以降でのみ導入されたため、潜在的な互換性があります。リスク。
IE の場合、最初にドキュメントの onreadystatechange イベントを登録します。テスト後、このメソッドはすべてのリソースがダウンロードされるまで待機します。
その後、IE でページが iframe 内にないと判断された場合は、呼び出しが成功するまで setTiemout を通じて documentElement の doScroll メソッドが呼び出され、DOMContentLoaded がトリガーされます。
jQuery はIE 用の新しいソリューション。http://javascript.nwbox.com/IEContentLoaded/ に由来します。 その原理は、IE では、DOM の一部のメソッドは DOM 解析が完了した後でのみ呼び出すことができるということです (doScroll はそのようなメソッドです)。つまり、doScroll を呼び出すことができるのは、DOM 解析が完了したときです。プロトタイプと同様に、document.write と比較して、このソリューションはページに iframe がある場合に失敗する問題を解決できます。また、jQuery はページが iframe 内にある場合にこのメソッドが失敗することを懸念しているようで、iframe 内にある場合はドキュメントの onreadystatechange を通じて実装され、そうでない場合は実装コードで判断されます。 doScroll を通じて実装されます。ただし、テスト後、doScroll は iframe でも引き続き有効です。
3. Moontools
コードをコピーします コードは次のとおりです:

(function(){
var domready = function(){
if (Browser.loaded) return;
Browser.loaded = true;
window.fireEvent('domready');
document.fireEvent('domready');
if (Browser.Engine.trident){
var temp = document.createElement('div'); ){
($try(function(){
temp.doScroll('left');
return $(temp).inject(document.body).set('html', 'temp' ).dispose ();
})) domready() : argument.callee.lay(50);
} else if (Browser.Engine.webkit && Browser.Engine) .version < ; 525){
(function(){
(['loaded', 'complete'].contains(document.readyState)) ? domready() : argument.callee.delay(50);
})();
} else {
window.addEvent('load', domready);
document.addEvent('DOMContentLoaded', domready); )() ;



実装アイデアは次のとおりです:

IE の場合は、doScroll メソッドを使用して実装します。
Webkit のバージョンが 525 より前の場合、document.readyState をポーリングすることで実装されます。
その他(FF/Webkit上位版/Opera)はDOMContentLoadedイベントを直接登録します。 Moontoolsの実装ソリューションプロトタイプとjQeuryを統合し、Webkitのバージョン判定によりソリューションをより堅牢にしています。 doScroll の実装に関しては、jQuery と比較して、ここで新しい div 要素が作成され、使用後に破棄されますが、jQuery は documentElement の doScroll を直接使用して検出するため、よりシンプルで効率的です。
4. Dojo




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

// START DOMContentLoaded
// Mozilla と Opera 9 は、使用できるイベントを公開します
if(document.addEventListener){
// 注意:
// Firefox 2.0 のスレッドの問題のため、そのプラットフォームでは
// DOMContentLoaded を有効にすることができません。詳細については、次を参照してください:
// http://trac.dojotoolkit.org/ticket/1704
if(dojo.isOpera || dojo.isFF >= 3 || (dojo.isMoz && dojo. config.enableMozDomContentLoaded === true)){
document.addEventListener("DOMContentLoaded", dojo._loadInit, null);
}
// 主に Opera 8.5 の場合、DOMContentLoaded がすでに起動されている場合は起動されません。
// trac #1640 のため Mozilla にも使用
window.addEventListener("load", dojo._loadInit, null);
}
if(dojo.isAIR){
window.addEventListener("load", dojo._loadInit, null);
}else if(/(WebKit|khtml)/i.test(navigator.userAgent)){ // スニフ
dojo._khtmlTimer = setInterval(function(){
if(/loaded|complete/ .test(document.readyState)){
dojo._loadInit(); // onload ハンドラーを呼び出します
}
}, 10);
}
// END DOMContentLoaded
(function(){
var _w = window;
var _handleNodeEvent = function(/*String*/evtName, /*Function*/fp){
// 概要:
// 指定された関数をノードの
// evtName ハンドラーに非破壊的に追加します。
// evtName: 「onclick」ハンドラーの場合は「onclick」の形式にする必要があります。 .
// 「on」部分を必ず渡してください。
var oldHandler = _w[evtName] ||
_w[evtName] = function(){ fp.apply(_w, argument);
oldHandler.apply(_w, argument);
if(dojo.isIE){
// Internet Explorer の場合。 readyState は init
// 呼び出しでは達成されませんが、Dojo では必要ありません。ただし、これを含めます
// 他の関数が追加されているかどうかは不明なので
/ / の可能性があります。ビルド プロセス
// で条件付きのコメントも含めてすべてのコメントが削除されるため、これは変更されていることに注意してください。 ' 'ipt defer="" src="//:" ="" onreadystatechange="if(this.readyState=='complete'){' dojo._scopeName '._loadInit();}">' ''
);
}
try{
document.namespaces.add("v","urn:schemas-microsoft-com:vml");
document.createStyleSheet().addRule("v\:*", "behavior:url(#default#VML)");
}catch(e){}
}
// 修正: dojo.unloaded には dojo スコープが必要なので、非関数ラッパーを使用します。
_handleNodeEvent("onbeforeunload", function() {
dojo.unloaded();
});
_handleNodeEvent("onunload", function() {
dojo.windowUnloaded();
});
})();



は次のように実行されます:

Opera または FF3 以降のバージョンの場合は、DOMContentLoaded< イベントを保護するために直接登録し、同時に window.onload イベントも登録します。
Air の場合は、widnow.onload イベントのみに登録されます。
IE の場合は、遅延遅延プロパティのスクリプトを面に書き込み、その onreadystatechange イベントに登録することによって実現されます。
Dojo の IE での実現方法では、iframe の問題が解決されておらず、FF2 以降には非常に奇妙なバグがあるため、FF3 以降のバージョンでは DOMContentLoaded イベントのみの使用が認められており、同時に構成も行われています。 -dojo.config.enableMozDomContentLoaded、FF でこの設定が true に設定されている場合、実行には DOMContentLoaded が使用されますが、これはプロトタイプと同様に十分に考慮されています。 🎜>五、YUI



复制代码

代码如下:

(function() {
/*! DOMReady: Dean Edwards/John Resig/Matthias Miller の著作に基づく */
// Internet Explorer: 遅延スクリプトの readState を使用します。
// これは、ドキュメントのreadyStateが
// 安全に操作できることを示唆する前に、
// DOMを操作するのに安全と思われる時点を分離します。
if (EU.isIE. ) {
//
// DOM の準備ができたら onAvailable/onContentReady アイテムを処理します。
YAHOO.util.Event.onDOMReady(
YAHOO.util.Event._tryPreloadAttach,
YAHOO. util.Event, true);
var n = document.createElement('p');
EU._dri = setInterval(function() {
try {
// doc の場合はエラーがスローされます準備ができていません
n.doScroll('left');
EU._dri = null
n = null;
} catch (ex) {
}
}, EU.POLL_INTERVAL);
// 現在、Safari のドキュメントの readState は、画像がロードされる前に
// ロード済み/完了に変わります。
} else if (EU.webkit && EU.webkit < 525) {
EU._dri = setInterval(function() {
var rs=document.readyState;
if ("loaded" == rs || "complete" == rs) {
clearInterval(EU._dri);
EU._dri = null;
EU._ready();
}
}、EU.POLL_INTERVAL);
// FireFox および Opera: これらのブラウザは、この
// 瞬間のイベントを提供します。最新の WebKit リリースでは、このイベントがサポートされるようになりました。
} else {
EU._simpleAdd(document, "DOMContentLoaded", EU._ready);
}
///////////////////////////////////////// //////////////////
EU._simpleAdd(window, "load", EU._load);
EU._simpleAdd(ウィンドウ, "アンロード", EU._unload);
EU._tryPreloadAttach();
})();


实现思路与Moontools一样

六、EXT

function initDocReady(){
var COMPLETE = "complete";
docReadyEvent = new Ext.util.Event();
if (Ext.isGecko || Ext.isOpera) {
DOC.addEventListener(DOMCONTENTLOADED, fireDocReady, false);
} else if (Ext.isIE){
DOC.write("");
DOC.getElementById(IEDEFERED).onreadystatechange = function(){
if(this.readyState == COMPLETE){
fireDocReady();
}
};
} else if (Ext.isWebKit){
docReadyProcId = setInterval(function(){
if(DOC.readyState == COMPLETE) {
fireDocReady();
}
}、10);
}
// 何があっても、ロード時に起動するようにしてください
E.on(WINDOW, "load", fireDocReady);
}


は、Dojo との一致を実現し、再説明はしません。 FF2 のバグを考慮して、DOMContentLoaded を使用するかどうかの設定を提供します。 🎜>

/*
* 注册浏览器の DOMContentLoaded イベント
* @param { Function } onready [必須]DOMContentLoaded イベント起動時に必要な実行対象関数
* @param { Object } config [任意] 構成 };
if( config )
for( var p in config)
this.conf[p] = config[p];
var isReady = false;
function doReady(){
if( isReady ) return;
//确保onready只执実行一回
isReady = true;
onready();
}
/*IE*/
if( Browser.ie ){
(function(){
if ( isReady ) return;
try {
document.documentElement .doScroll("left");
} catch( エラー ) {
setTimeout( argument.callee, 0 );
}
doReady(); ();
window.attachEvent('onload',doReady);
}
/*Webkit*/
else if (Browser.webkit && Browser.version < 525){
(function(){
if( isReady ) return;
if (/loaded|complete/.test(document.readyState))
doReady();
else
setTimeout( argument.callee, 0 )
});
window.addEventListener('load',doReady,false);
}
/*FF Opera 高版 webkit その他*/
else{
if( !Browser.ff || Browser.version != 2 || this.conf.enableMozDOMReady)
document.addEventListener( "DOMContentLoaded", function(){
document.removeEventListener( "DOMContentLoaded", argument.callee, false );
doReady();
}, false );
window.addEventListener('load',doReady,false);
}
}

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