LOGO: 深埋在最最狂野的季节
WWW.VGOT.NET
My heart is like an open highway, Like franke said I did it my way.
科技创造力量,网络成就梦想。凝聚天下,开阔眼界

JS 替换 window.onload 的 document.ready

发布时间:2010/04/10 20:17 分类:Web前端 作者:pader 点击:171791
Web前端

通常我们想要在页面内容加载完成后运行 JS 时,都会使用 window.onload 来处理,比如:

window.onload = function(){
  alert('Hello World!');
};

这段代码将在页面载入完成后弹出一个 "Hello World!" 的警告框,但是众所周知,window.onload 的特点是页面元素全部加载完成后才执行,比如页面内有大量的图片之类,当打开网页时,其实相关的 DOM 已经全部加载完成,此时已经可以执行你想要执行的脚本了,可是图片的加载速度要很慢于页面的 HTML,这显然在大多数情况下不是我们想要的。

jQuery 提供一个 $(document).ready(); 来解决此问题,当页面 DOM 加载完成后,ready() 里的函数便会立即执行,但如果我们在不使用 jQuery 的情况下呢?
好了,废话不多说,大家都明白想要什么,以下是来自国外网站的一段代码,功能同等于 jQuery 的 $(document).ready();

看代码:

(function () {
  var ie = !!(window.attachEvent && !window.opera);
  var wk = /webkit\/(\d+)/i.test(navigator.userAgent) && (RegExp.$1 < 525);
  var fn = [];
  var run = function () { for (var i = 0; i < fn.length; i++) fn[i](); };
  var d = document;
  d.ready = function (f) {
    if (!ie && !wk && d.addEventListener)
      return d.addEventListener('DOMContentLoaded', f, false);
    if (fn.push(f) > 1) return;
    if (ie)
      (function () {
        try { d.documentElement.doScroll('left'); run(); }
        catch (err) { setTimeout(arguments.callee, 0); }
      })();
    else if (wk)
      var t = setInterval(function () {
        if (/^(loaded|complete)$/.test(d.readyState))
          clearInterval(t), run();
      }, 0);
  };
})();

把这段代码放到你的页面中或者某个导入的脚本中,然后你就可以像下面这样使用了:
document.ready(function(){
  alert('Document is ready!');
});

打开页面,看到效果没?YES,这就是去掉了 $(); 的 document.ready(); 咱不再依赖 jQuery,但如果你的站点已经使用了 jQuery,就不用再多此一举了。
如果你并没有感觉到明显的区别,你可以到百度里随便便搜一张很大加载速度又慢的图片放到页面里试一试,打开一看,效果就很明显了。

下面还有一个来自于 PHPWind 论坛程序中某个脚本中的函数片段:

~function() {
  var FNArray=[];
  var D = document;
  /**
   * 使用举例:
    window.onReady(FunctionName[,argu1,[argu2,[....]]]);
   */
  window.onReady = function(fallBackFunction) {
  
    var argu=[];
    for(var i=1,len=arguments.length; i<len; i++) {
      argu.push(arguments[i]);
    }
    var is_ie = !!(window.attachEvent && !window.opera); //增加的
    if(window.readyBound) return fallBackFunction.apply(this,argu);
    if(!is_ie) return   fallBackFunction.apply(this,argu);
    FNArray.push(fallBackFunction);
    readyBound = true;
    var ready = 0;
    //Mozilla, Opera and webkit nightlies currently support this event
    if(D.addEventListener) {
      //Use the handy event callback
      D.addEventListener("DOMContentLoaded", function() {
        D.removeEventListener("DOMContentLoaded", arguments.callee, false);
        if(ready) return;
        ready = 1;
        for(var i=0,len=FNArray.length; i<len; i++) {
          FNArray[i] ? FNArray[i].apply(this,argu) : 0;
        }
      }, false);

    // If IE event model is used
    } else if(D.attachEvent) {
      // ensure firing before onload,
      // maybe late but safe also for iframes
      D.attachEvent("onreadystatechange", function() {
        if(D.readyState === "complete") {
          D.detachEvent("onreadystatechange", arguments.callee);
          if (ready) return;
          ready = 1;
          for(var i=0,len=FNArray.length; i<len; i++) {
            FNArray[i] ? FNArray[i].apply(this,argu) : 0;
          }
        }
      });

      // If IE and not an iframe
      // continually check to see if the D is ready
      if(D.documentElement.doScroll && window == window.top)(function() {
        if(ready) return;
        try {
          // If IE is used, use the trick by Diego Perini
          // http://javascript.nwbox.com/IEContentLoaded/
          D.documentElement.doScroll("left");
        } catch(error) {
          setTimeout(arguments.callee, 0);
          return;
        }
        ready = 1;
        for (var i=0,len=FNArray.length; i<len; i++) {
          FNArray[i] ? FNArray[i].apply(this,argu) : 0;
        }
      })();
    }
  };
}();

这段的用法是:
window.onReady(function(){
  alert('Bingo~!');
});

两个原理相同,唯一不同的区别是 window.onReady() 除了第一个参数可以传递要执行的函数外,还可以在后面的参数传递要传给第一个参数函数中的参数...额,前面这句话怎么这么别扭呢..意思就是 onReady 第一个参数之后的参数都将作为另外的参数传递给第一个参数的函数..好像还有点别扭??不管了,你自己理解了,总之这个传参的功能用的不多。
window.onReady(); 的传参功能实际用处不多,实现方法也是一样,代码这么多,当然还是推荐使用 document.ready();

其实 window.onload 也并非是一无用处,很多情况下一些B/S软件需要页面全部加载后才提供用户相关功能,这样 window.onload 就可以提供一种“加载中”的功能,又或者是页面内容很少,完全无需 document.ready(); 根据各种情况,应该合理的使用 onload 和 ready。

最后提供压缩版 document.ready();

(function () {
   var ie =!!(window.attachEvent&&!window.opera),wk=/webkit\/(\d+)/i.test(navigator.userAgent)&&(RegExp.$1<525);
   var fn =[],run=function(){for(var i=0;i<fn.length;i++)fn[i]();},d=document;d.ready=function(f){
   if(!ie&&!wk&&d.addEventListener){return d.addEventListener('DOMContentLoaded',f,false);}if(fn.push(f)>1)return;
   if(ie)(function(){try{d.documentElement.doScroll('left');run();}catch(err){setTimeout(arguments.callee,0);}})();
   else if(wk)var t=setInterval(function(){if(/^(loaded|complete)$/.test(d.readyState))clearInterval(t),run();},0);};
})();

本文内容由 VGOT Design 原创,转载请保留原文链接:http://www.vgot.net/?A65.htm

网友评论
  • 评论正在加载...
发表评论
名字: 主页: 邮箱:
© Copyrights VGOT.NET 2008-2009 皖ICP备17000202号-1
Processed in 0.01283 second(s), 5 Queries, Memory 573.48 KB.