Summary of six ways to realize Jsdomready event

Source: Internet
Author: User
In practical applications, we often encounter scenarios where the page loads and does something: bound events, DOM operations, some nodes, and so on.

The original is more commonly used is the OnLoad event window, and the actual effect of the event is: when the page parsing/dom Tree was established, and completed the tablets, scripts, stylesheets and even all the resources in the IFRAME after the download is triggered.

This is a little too "late" for many practical applications, which can affect the user experience more.

To solve this problem, a domcontentloaded method is added to the FF, which is triggered earlier than onload, which is triggered when the page's DOM content is loaded, without waiting for the other resources to load.

The Webkit engine also introduced the event starting with version 525 (Webkit nightly 1/2008:525+), which is also included in opera. So far the mainstream IE still has no meaning to add.

Although the IE is not, but there is always a solution, the following comparison of a few major mainstream framework for the event of the compatibility version of the implementation of the scheme, 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|com Plete/.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 = nul L Firecontentloadedevent (); } }; } })();

The following ideas are implemented:

If it is WebKit, the ReadyState property of the document is polled, and if the value of this property is loaded or complete, the domcontentloaded event is triggered, and the event is registered on Window.onload for insurance purposes.

If FF, register the domcontentloaded event directly.

If it is IE then use document.write to add a SCRIPT element to the page, and set the Defer property, and finally, the script is loaded complete as a domcontentloaded event to trigger.

The implementation of the problem is mainly two points: first, through document.write write script and set the method of defer in the case of the page contains an IFRAME, will wait until the content inside the IFRAME is loaded after the trigger, which is not much different from onload; WebKit introduced the Domcontentloaded method in more than 525 versions, so it is no longer possible to do this by polling in these versions, which can be optimized.

Second, JQuery

function Bindready () {if (readybound) return; readybound = true;//Mozilla, Opera and WebKit nightlies currently Suppor T this event if (Document.addeventlistener) {//Use the handy event callback Document.addeventlistener ("Domcontentload Ed ", 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 a LSO for IFRAMEs document.attachevent ("onReadyStateChange", function () {if (document.readystate = = = "complete") {Documen T.detachevent ("onReadyStateChange", Arguments.callee); Jquery.ready (); } }); If IE and not a IFRAME//continually check to see if the document was ready if (Document.documentElement.doScroll &am p;& typeof window.frameelement = = = "undefined") (function () {if (jquery.isready) return; try {//If IE is used, US E 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); }

The following ideas are implemented:

The same treatment as WebKit and Firefox, are directly registered domcontentloaded events, but because WebKit is introduced in more than 525 version, so there is a potential for compatibility.

For IE, the first registration document onReadyStateChange event, tested, this way and window.onload equivalent, will still wait until all the resources downloaded after the trigger.

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

Out Trigger domcontentloaded

jquery's solution for IE uses a new approach derived from http://javascript.nwbox.com/IEContentLoaded/. The principle is that, under IE, some of the DOM's methods can only be called after DOM parsing is complete, doscroll is such a method, in turn, when the doscroll can be called when the DOM parsing is completed, 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 the IFRAME, the method will be invalidated, so the implementation of the code to make a judgment, if it is in the IFRAME through the document onReadyStateChange to achieve, otherwise through the doscroll to achieve. However, even in the IFRAME, the 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 () {temp.doscroll (  ' left ');  return $ (temp). Inject (document.body). Set (' HTML ', ' temp '). Dispose ();  }) ? Domready (): Arguments.callee.delay ();  }) ();  } else if (Browser.Engine.webkit && Browser.Engine.version < 525) {  (function () {(  [' Loaded ', ' Complete '].contains (document.readystate))? Domready (): Arguments.callee.delay ();  }) ();  } else {  window.addevent (' Load ', domready);  Document.addevent (' domcontentloaded ', domready);  }  ) ();

Iv. Dojo

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, see://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 be 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 your pass in 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 is not being achieved on INIT/call, but Dojo doesn ' t need it howev Er, we ' ll include it//because we don ' t know if there is other functions added that//might.  Note that this have 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 ();} "  > ' + ' </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 ();}); })();

The following ideas are implemented:

If it is opera or FF3, the domcontentloaded< event is registered directly, for insurance purposes, and also for the Window.onload event.

For WebKit, it is done by polling the document.readystate.

If it is air, only the Widnow.onload event is registered.

If IE, it is implemented by writing a script with the defer property to the page and registering its onReadyStateChange event.

The implementation of dojo under IE also does not solve the problem of IFRAME, and because there will be a very strange bug in FF2, so the default only in FF3 above version of the Domcontentloaded event, but also give a configuration- dojo.config.enableMozDomContentLoaded, if the configuration is set to True under FF, it will still be implemented using domcontentloaded, which takes the flexibility into account. For the implementation of WebKit, there is the same space as the prototype optimization.

Five, YUI

Internet Explorer:use The readyState of a defered script. This isolates "what appears" is a safe moment to manipulate//the DOM prior to when the document ' s readyState sugges  TS//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 is 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 is 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 idea as Moontools

Six, 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);  };

The realization of the idea of the same as dojo, no longer redundant complaints.

Summarize

Summarize the practice of the major mainstream framework, wrote the following version. The main is to optimize and consider the FF2 under the bug, provide a switch configuration whether to use domcontentloaded.

function ondomcontentloaded (onready,config) {//browser detects related objects, here to save code is not implemented, actual use needs to be implemented.  var Browser = {};  Set whether to use domcontentloaded under FF (there is 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 executes only 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 summarize is the small part of the whole content to share to everyone, hope to give you a reference, but also hope that we support topic.alibabacloud.com.

Related Article

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.