window.onload的替代方案——DOM状态检测

window.onload是非常常用的初始化事件,而该事件所对应的响应函数只有在浏览器将目标页面中所有资源内容全部装载完毕之后才会执行,这里的“所有资源内容”特指图片、音效、iframe所包含的页面等。

下面的例子是使用window.onload方式执行JavaScript脚本:

  1. window.onload=function(){  walkmydog()}  

Firefox & Opera下的替换方案:

  1. if (document.addEventListener)  
  2.   document.addEventListener("DOMContentLoaded", walkmydog, false)  

IE下的替换方案,:

  1. if (document.all && !window.opera){ //Crude test for IE  
  2. //Define a "blank" external JavaScript tag  
  3.   document.write('<script type="text/javascript" id="contentloadtag" defer="defer" src="javascript:void(0)"><\/script>')  
  4.   var contentloadtag=document.getElementById("contentloadtag")  
  5.   contentloadtag.onreadystatechange=function(){  
  6.     if (this.readyState=="complete")  
  7.       walkmydog()  
  8.   }  
  9. }  

Firefox & Opera & IE综合方案:

  1. var alreadyrunflag=0 //flag to indicate whether target function has already been run  
  2.   
  3. if (document.addEventListener)  
  4.   document.addEventListener("DOMContentLoaded"function(){<span style="color: rgb(255, 0, 0); ">alreadyrunflag=1;</span> walkmydog()}, false)  
  5. else if (document.all && !window.opera){  
  6.   document.write('<script type="text/javascript" id="contentloadtag" defer="defer" src="javascript:void(0)"><\/script>')  
  7.   var contentloadtag=document.getElementById("contentloadtag")  
  8.   contentloadtag.onreadystatechange=function(){  
  9.     if (this.readyState=="complete"){  
  10.       <span style="color:#ff0000;">alreadyrunflag=1;</span>  
  11.       walkmydog()  
  12.     }  
  13.   }  
  14. }  
  15.   
  16. window.onload=function(){  
  17.   <span style="color:#ff0000;">setTimeout("if (!alreadyrunflag) walkmydog()", 0);</span>  
  18. }  

之所以要用window.onload是为了应对那些既不支持DOMContentLoaded也不支持onreadystatechange的浏览器。setTimeout函数的作用是为了保证变量alreadyrunflag在window.onload事件被激活之前已经赋值。因为有时在IE浏览器中,由于要装载资源几乎没有,导致window.onload和onreadystatechange事件同时激活,这样的话,在onload事件做判断时变量alreadyrunflag可能还没有被赋值,这就无法保证程序执行的正确性。所以用setTimeout函数来让onload事件中的判断条件稍微滞后一些,以保证alreadyrunflag可用。

下面是原文中用在Safari中的方案:

  1. if(/Safari/i.test(navigator.userAgent)){ //Test for Safari  
  2.   var _timer=setInterval(function(){  
  3.   if(/loaded|complete/.test(document.readyState)){  
  4.     clearInterval(_timer)  
  5.     walkmydog() // call target function  
  6.   }}, 10)  
  7. }  

这种方案是就是单纯的检测document的状态。至于为什么不使用DOMContentLoaded,可能是和文章所写时的Safari版本有关吧。从http://en.wikipedia.org/wiki/DOM_events可以看出,Safari3.1+就开始支持DOMContentLoaded了,可喜的是IE9也支持了(http://p2b.jp/1269996654,同时支持的还有addEventListener)。不过这种方案也许还会有用,最差也可以帮我们开阔下眼界。
以上内容大部分来自:http://www.javascriptkit.com/dhtmltutors/domready.shtml。其中添加了点自己理解。

原文地址:https://www.cnblogs.com/mfryf/p/2348101.html