Six ways to realize the JS Domready event _javascript Skills

Source: Internet
Author: User
Tags setinterval versions

In practical applications, we often encounter such a scenario, when the page is completed after loading to do something: binding events, Dom operation of some nodes, and so on.

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:

1. Prototype
2. Jqeury
3. Moontools
4. Dojo
5. Yui
6. Ext

First, Prototype

Implementation code

(function () {

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 is mainly two points: first, through the document.write write script and set defer in the page contains an IFRAME, will wait until the contents of the IFrame loaded before triggering, This is not much different from the onload; second, WebKit introduced the Domcontentloaded method in more than 525 versions, so there is no need for polling to be implemented in these versions to optimize.

Second, JQuery

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 SAF e also for IFRAMEs document.attachevent ("onReadyStateChange", function () {if (document.readystate = = "complete") {D

Ocument.detachevent ("onReadyStateChange", Arguments.callee);

Jquery.ready ();

}

}); If IE and not a IFRAME//continually check to-if the document is ready if (Document.documentElement.doScroll &

amp;& typeof window.frameelement = = "undefined") (function () {if (jquery.isready) return; try {//If IE used, use 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 would 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.

After that, if it is IE and the page is not in the IFRAME, the DocumentElement DoScroll method is constantly called through Settiemout until the call succeeds

Out Trigger 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

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

Four, Dojo

START domcontentloaded//Mozilla and Opera 9 expose the event we could use if (Document.addeventlistener) {//NO TE://Due to a threading issue into Firefox 2.0, we can ' t enable//domcontentloaded on that platform. For more information, 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 (Evtname, 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 Ever, we ' ll include it//because we don ' t know if there are other functions and added.
 
This is the has changed because the build process//strips all comments-including conditional. if (!dojo.config.afteronload) {document.write (' <scr ' + ' IPT defer= ' "src="//: "+ =" "onreadystatechange=" if ( This.readystate==\ ' complete\ ') {' + Dojo._scopename + '. _loadinit ();} ' > ' + ' </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

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 Sugge
 
STS//It is 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_x (' P ');
 
Eu._dri = setinterval (function () {try {//throws an error if Doc isn't 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'll//change to Loaded/complete before images are.
 
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

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 ("<s" + ' cript id= "+ iedefered +" defer= "defer" src= "/' + '/:" ></s "+ ' cript>");
 
Doc.getelementbyid (iedefered). onreadystatechange = function () {
 
if (this.readystate = = COMPLETE) {
 
Firedocready ();
 
}
 
;
 
} else if (ext.iswebkit) {
 
docreadyprocid = setinterval (function () {
 
if (doc.readystate = = COMPLETE) {
 
Firedocready ();
 
}
 
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

Summarize the practices of the major mainstream frameworks and 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.

function ondomcontentloaded (onready,config) {//browser detects related objects, which you need to implement when saving code is not implemented.
 
var Browser = {};
 
Sets 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 ();
 
} if (browser.ie) {(function () {if (isready) return;
 
try {document.documentElement.doScroll ("left");
 
catch (Error) {settimeout (Arguments.callee, 0);
 
Return
 
} doready ();
 
})();
 
Window.attachevent (' onload ', doready);
 
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); } 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); }
 
}

Above this JS Domready event six ways to sum up is a small series to share all the content, hope to give you a reference, but also hope that we support the cloud-dwelling community.

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.