A summary of the implementation of Domready events in some mainstream JS frames _jquery

Source: Internet
Author: User
Tags setinterval
The most commonly used is the OnLoad event of window, and the actual effect of the event is: when the page parsing/dom tree is completed and completed, such as pictures, scripts, style sheets and even all the resources in the IFRAME download before triggering. This is a bit too "late" for many practical applications, and it's more impacting the user experience. To solve this problem, FF adds a domcontentloaded method, which, when compared to onload, triggers earlier, triggering when the page's DOM content is loaded, without waiting for other resources to load. The Webkit engine also introduced the event from the version 525 (Webkit nightly 1/2008:525+), which is also included in opera. So far the mainstream of IE still do not want to add meaning. Although IE does not, but there is always a solution, the following comparison of several major framework for the event compatibility version of the implementation of the scenario, the framework involved include:
Prototype
Jqeury
Moontools
Dojo
Yui
Ext
First, Prototype
Implementation code
Copy Code code as follows:

(function () {
/* Support for the domcontentloaded event was based on work by Dan Webb,
Matthias Miller, Dean Edwards and John Resig. */
var timer;
function Firecontentloadedevent () {
if (document.loaded) return;
if (timer) window.clearinterval (timer);
Document.fire ("dom:loaded");
Document.loaded = true;
}
if (Document.addeventlistener) {
if (Prototype.Browser.WebKit) {
Timer = Window.setinterval (function () {
if (/loaded|complete/.test (document.readystate))
Firecontentloadedevent ();
}, 0);
Event.observe (window, "load", firecontentloadedevent);
} else {
Document.addeventlistener ("domcontentloaded",
Firecontentloadedevent, false);
}
} else {
document.write ("<" + "script id=__ondomcontentloaded defer src=//:><\/script>");
$ ("__ondomcontentloaded"). onreadystatechange = function () {
if (this.readystate = = "complete") {
This.onreadystatechange = null;
Firecontentloadedevent ();
}
};
}
})();

Realize the following ideas:
If it is WebKit, the ReadyState property of the document is polled, and if the value of the property is loaded or complete triggers the domcontentloaded event, the event is registered to the window.onload for insurance purposes.
If it is FF, register the domcontentloaded event directly.
If it is IE, use document.write to add a SCRIPT element to the page and set the Defer property, and finally the completion of the script as a domcontentloaded event to trigger.
The implementation of the problem of the main two points: first, through the document.write write script and set the defer in the page contains an IFRAME, will wait until the contents of the IFRAME after loading to trigger, this is not too much difference with the onload; WebKit introduced the Domcontentloaded method in more than 525 versions, so there is no need for polling to be implemented in these versions, which can be optimized.
Second, JQuery
Copy Code code as follows:

function Bindready () {
if (Readybound) return;
Readybound = true;
Mozilla, Opera and WebKit nightlies currently support this event
if (Document.addeventlistener) {
Use the handy event callback
Document.addeventlistener ("domcontentloaded", function () {
Document.removeeventlistener ("domcontentloaded", Arguments.callee, false);
Jquery.ready ();
}, False);
If IE event model is used
else if (document.attachevent) {
Ensure firing before onload,
Maybe late but safe also for IFRAMEs
Document.attachevent ("onReadyStateChange", function () {
if (document.readystate = = "complete") {
Document.detachevent ("onReadyStateChange", Arguments.callee);
Jquery.ready ();
}
});
If IE and not an IFRAME
Continually check to-if the document is ready
if (document.documentElement.doScroll && typeof window.frameelement = = "undefined") (function () {
if (Jquery.isready) return;
try {
If IE is used with the trick by Diego Perini
http://javascript.nwbox.com/IEContentLoaded/
Document.documentElement.doScroll ("left");
catch (Error) {
settimeout (Arguments.callee, 0);
Return
}
and execute any waiting functions
Jquery.ready ();
})();
}
A fallback to window.onload, that'll always work
JQuery.event.add (window, "load", jquery.ready);
}

realize the following ideas:
WebKit and Firefox are treated as equals, are directly registered domcontentloaded events, but because WebKit is introduced in more than 525 version, there is a potential for compatibility.
For IE, the first registration document of the onReadyStateChange event, tested, this way and window.onload, will still wait until all resources downloaded after the trigger.
Then, to determine if IE and the page is not in the IFRAME, then through the settiemout to constantly call the DocumentElement DoScroll method, until the success of the call will be triggered domcontentloaded
jquery uses a new approach to IE solutions from http://javascript.nwbox.com/IEContentLoaded/. The principle is that, under IE, some DOM methods can only be invoked when DOM parsing is complete, DoScroll is a method that, in turn, is when DOM parsing is complete when the doscroll is called. Compared with the document.write in prototype, this scheme can solve the problem that the page has an IFRAME failure. In addition, JQuery seems to worry that when the page is in an IFRAME, the method will fail, so the implementation of the code is judged, if it is in the IFRAME through the onreadystatechange of the document, otherwise through the doscroll to achieve. However, after testing, even in the IFRAME, DoScroll is still valid.
Third, Moontools
Copy Code code as follows:

(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 ');
(function () {
($try (function () {
Temp.doscroll (' left ');
return $ (temp). Inject (document.body). Set (' HTML ', ' temp '). Dispose ();
})) ? Domready (): Arguments.callee.delay (50);
})();
else if (Browser.Engine.webkit && Browser.Engine.version < 525) {
(function () {
([' Loaded ', ' Complete '].contains (document.readystate))? Domready (): Arguments.callee.delay (50);
})();
} else {
Window.addevent (' Load ', domready);
Document.addevent (' domcontentloaded ', domready);
}
})();

realize the following ideas:
If it is IE then use the DoScroll method to achieve.
If the WebKit is less than 525, it is implemented by polling document.readystate.
Other (Ff/webkit/opera) directly register domcontentloaded event
Moontools implementation of the prototype and Jqeury in the synthesis, the WebKit version of the decision makes the scheme more robust. In terms of DoScroll implementations, this is a new DIV element, compared to jquery, and destroyed after use, while jquery uses the documentelement doscroll to detect it more simply and efficiently.
Four, Dojo
Copy Code code as follows:

START domcontentloaded
Mozilla and Opera 9 expose the event we could use
if (Document.addeventlistener) {
Note:
Due to a threading issue in Firefox 2.0, we can ' t enable
Domcontentloaded on that platform. For more information, here:
http://trac.dojotoolkit.org/ticket/1704
if (Dojo.isopera | | DOJO.ISFF >= 3 | | (Dojo.ismoz && dojo.config.enableMozDomContentLoaded = = True)) {
Document.addeventlistener ("domcontentloaded", dojo._loadinit, NULL);
}
Mainly for Opera 8.5, won ' t is fired if domcontentloaded fired already.
Also used for Mozilla because of TRAC #1640
Window.addeventlistener ("Load", dojo._loadinit, NULL);
}
if (Dojo.isair) {
Window.addeventlistener ("Load", dojo._loadinit, NULL);
}else if (/(webkit|khtml)/i.test (navigator.useragent)) {//sniff
Dojo._khtmltimer = setinterval (function () {
if (/loaded|complete/.test (document.readystate)) {
Dojo._loadinit (); Call the onload handler
}
}, 10);
}
End domcontentloaded
(function () {
var _w = window;
var _handlenodeevent = function (/*string*/evtname,/*function*/fp) {
Summary
Non-destructively adds the specified function to the node ' s
Evtname handler.
Evtname:should is in the form "onclick" for "onclick" handlers.
Make sure the ' on ' part.
var oldhandler = _w[evtname] | | function () {};
_w[evtname] = function () {
Fp.apply (_w, arguments);
Oldhandler.apply (_w, arguments);
};
};
if (Dojo.isie) {
For Internet Explorer. ReadyState won't is achieved on Init
Call, but Dojo doesn ' t need it however, we ' ll include it
Because we don ' t know if there are other functions added
Might. This is the has changed because the build process
Strips all comments--including conditional ones.
if (!dojo.config.afteronload) {
document.write (' <scr ' + ' IPT defer= "" src= "//:" + + "" onreadystatechange= "if (this.readystate==\ ' complete\ ') {' + Dojo . _scopename + '. _loadinit ();} " > '
+ ' &LT;/SCR ' + ' ipt> '
);
}
try{
Document.namespaces.add ("V", "urn:schemas-microsoft-com:vml");
Document.createstylesheet (). addrule ("V\\:*", "Behavior:url (#default #vml)");
}catch (e) {}
}
FIXME:dojo.unloaded requires dojo scope, so using anon function wrapper.
_handlenodeevent ("onbeforeunload", function () {
Dojo.unloaded ();
});
_handlenodeevent ("OnUnload", function () {
Dojo.windowunloaded ();
});
})();

realize the following ideas:
If it is opera or FF3 above version is directly registered domcontentloaded< event, for the sake of insurance, but also registered Window.onload event.
For WebKit, this is done by polling the document.readystate.
If it is air, only the Widnow.onload event is registered.
If it is IE, it is accomplished by writing a script with the defer attribute to the page and registering its onReadyStateChange event.
The implementation of dojo in IE can not solve the problem of IFRAME, and because there is a very strange bug under the FF2, so the default only in FF3 above version of the Domcontentloaded event, but also gave a configuration- dojo.config.enableMozDomContentLoaded, if the configuration is set to True under FF, it will still be implemented using domcontentloaded, which takes full account of the flexibility. For the implementation of WebKit, as with prototype, there is room for optimization.
Five, YUI
Copy Code code as follows:

(function () {
/*! domready:based on work By:dean edwards/john resig/matthias Miller * *
Internet Explorer:use The readyState of a defered script.
This is isolates what appears to being a safe moment to manipulate
The DOM prior to when the document ' s readyState suggests
It's safe to do.
if (Eu.isie) {
Process Onavailable/oncontentready items when the
DOM is ready.
YAHOO.util.Event.onDOMReady (
Yahoo.util.event._trypreloadattach,
YAHOO.util.Event, True);
var n = document.createelement (' P ');
Eu._dri = setinterval (function () {
try {
Throws an error if Doc are not ready
N.doscroll (' left ');
Clearinterval (Eu._dri);
Eu._dri = null;
Eu._ready ();
n = null;
catch (ex) {
}
}, EU. Poll_interval);
The document ' s readyState in Safari currently would
Change to Loaded/complete before images are loaded.
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 and Opera:these browsers provide a event for this
Moment. The latest WebKit releases now support this event.
} else {
Eu._simpleadd (document, "domcontentloaded", Eu._ready);
}
/////////////////////////////////////////////////////////////
Eu._simpleadd (window, "load", eu._load);
Eu._simpleadd (window, "unload", eu._unload);
Eu._trypreloadattach ();
})();

Realize the same ideas as Moontools
Liu, EXT
Copy Code code as follows:

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 ("<script id=" + iedefered + defer=defer src= '/%27+%27/: ' ></script> ');
Doc.getelementbyid (iedefered). onreadystatechange = function () {
if (this.readystate = = COMPLETE) {
Firedocready ();
}
};
else if (Ext.iswebkit) {
Docreadyprocid = setinterval (function () {
if (doc.readystate = = COMPLETE) {
Firedocready ();
}
}, 10);
}
No matter what, make sure it fires on load
E.ON (window, "load", firedocready);
}

To achieve the same ideas and dojo, no longer redundant complaints.
Summarize
Summing up the practices of the major mainstream frameworks, write the following version. The main is to optimize as much as possible and take into account the bug under the FF2, to provide a use of domcontentloaded switch configuration.
Copy Code code as follows:

/*
* Register the browser's domcontentloaded event
* @param {function} Onready [required] functions that need to be performed when a domcontentloaded event is triggered
* @param {Object} config [optional] configuration item
*/
function ondomcontentloaded (onready,config) {
The browser detects related objects, which in order to save code is not implemented, you need to implement the actual use.
var Browser = {};
Set whether to use domcontentloaded under FF (a bug in a particular scene under FF2)
this.conf = {
Enablemozdomready:true
};
if (config)
For (var p in config)
THIS.CONF[P] = config[p];
var isready = false;
function Doready () {
if (IsReady) return;
Make sure Onready only executes once
IsReady = true;
Onready ();
}
/*ie*/
if (browser.ie) {
(function () {
if (IsReady) return;
try {
Document.documentElement.doScroll ("left");
catch (Error) {
settimeout (Arguments.callee, 0);
Return
}
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 (Arguments.callee, 0);
})();
Window.addeventlistener (' Load ', doready,false);
}
/*FF Opera High Edition WebKit Other * *
else{
if (! Browser.ff | | Browser.version!= 2 | | This.conf.enableMozDOMReady)
Document.addeventlistener ("domcontentloaded", function () {
Document.removeeventlistener ("domcontentloaded", Arguments.callee, false);
Doready ();
}, False);
Window.addeventlistener (' Load ', doready,false);
}
}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.