天天看点

window.onload问题解决啦!

 原文地址: http://dean.edwards.name/weblog/2005/09/busted/ 我所谓的解决只是针对两款主要的浏览器——IE和Mozilla/Firefox。难道这还不够吗? 首先,让我先定义这个问题。程序员在他们的web应用程序的最开始调用window.onload 事件。对于菜单的动态效果或者更复杂的事情,如邮件系统的初始化,使用这个事件是很平常的。但是问题就在于onload事件会在所有页面内容(包括图片和其它二进制内容)被加载后才会触发。如果你的页面包含了大量的图片,那么你可能会发现在页面激活之前有一个显著的延迟。我们想做的就是寻找一种方法来确定DOM被完全的加载时不用等待所有那些讨厌的图片加载完毕。 Mozilla提供了一个特定的事件DOMContentLoaded。下面的代码准确的实现了在Mozilla平台下,我们想要解决的问题:

window.onload问题解决啦!
//  Mozilla浏览器
window.onload问题解决啦!
window.onload问题解决啦!
window.onload问题解决啦!
if  (document.addEventListener)  ... {
window.onload问题解决啦!
  document.addEventListener("DOMContentLoaded", init, false);
window.onload问题解决啦!
}

那么IE怎么办呢? IE对

<script>标签

提供一个非常方便的属性:defer。这个属性的意义是指示IE延迟脚本的加载直到DOM被加载。但是这仅仅对外部脚本起作用。另一个重要的问题是,这个属性不能使用脚本动态的添加。这意味着,你不能使用DOM方法创建一个脚本并且设置defer属性,因为这会被忽略。 使用方便的defer属性,我们能够创建一个一小段脚本来调用我们的onload事件

window.onload问题解决啦!
< script  defer src ="ie_onload.js"  type ="text/javascript" ></ script >

这个外部脚本的内容仅仅是一行代码,用来调用我们的onload事件:

init();
  
       

使用这个方法,这就不算问题了。但是其他浏览器会忽略defer属性并立即加载脚本。这里有一些方法来绕过这个问题。我钟爱的方法是使用 条件注释对其他浏览器隐藏这段脚本。

window.onload问题解决啦!
<!-- [if IE]><script defer src="ie_onload.js"></script><![endif] -->

IE也支持 条件编译。下面的JavaScript代码和上面的HTML是等效的

window.onload问题解决啦!
//  IE浏览器
window.onload问题解决啦!
window.onload问题解决啦!
window.onload问题解决啦!
/**/ /*@cc_on @*/
window.onload问题解决啦!
window.onload问题解决啦!
/**/ /*@if (@_win32)
window.onload问题解决啦!
  document.write("<script defer src=ie_onload.js></script>");
window.onload问题解决啦!
/*@end @*/

到目前为止看起来一切顺利?我们现在需要支持其他的浏览器。我们只有一个选择——标准的window.onload事件:

window.onload问题解决啦!
//  其他浏览器
window.onload问题解决啦!
window.onload问题解决啦!
window.onload  =  init;

现在就剩下一个问题了(谁说这个问题简单?)。因为对于其他浏览器我们只能使用onload事件,但是对于IE和Mozilla,我们会调用两次init方法。为了避开这个问题,我们应当做一个标志方法,以至于onload事件只执行一次。所以我们的init方法会像下面的代码一样:

window.onload问题解决啦!
window.onload问题解决啦!
function  init()  ... {
window.onload问题解决啦!
//如果这个方法已经被调用过,就推出
window.onload问题解决啦!
  if (arguments.callee.done) return;
window.onload问题解决啦!
//标志这个方法以至于我们不会做同样的事情两次
window.onload问题解决啦!
  arguments.callee.done = true;
window.onload问题解决啦!
window.onload问题解决啦!
  // 其他操作
window.onload问题解决啦!
} ;
And that, as they say, is that.      

我提供了一个 例子,来证明这个技术。  

继续阅读