zoukankan      html  css  js  c++  java
  • 比Jquery的document.ready更快的方法

    新的版本放弃使用document.write()(实际上我们依赖的是script标签的defer触发机制),主要基于如下几个理由:

    1. XHTML不支持document.write
    2. 当页面上的资源非常少时,会晚于window.onload
    3. document.write有时会覆写我们原有的DOM
    4. document.write生成的script不能通过内部函数移除

    外国javascript高手Diego Perini于是发掘了doScroll这个方法。在IE下,doScroll方法存在于所有标签。但我搞来搞去,发现光是doScroll也不行,时不时就发现window.onload执行于domReady之前。只有结合onreadystatechange与doScroll这两个方法,我们才能在IE中搞出与标准浏览器相同的结果。因此你在jQuery,Prototype,swfobject,Ext等类库看到它们共同出现。而onreadystatechange其实也有些问题的,具体自己可能google一下,因此2006年左右实现domReady的代码基本依仗于document.write()。嗯,剩下的我就在代码间的注释中说明吧,这样更一目了解。

    /* 
    take from dom library version 1.0, inspired by  jQuery 
    Copyright 2010-2011 (2011.2.27更新) 
    Dual licensed under the MIT or GPL Version 2 licenses. 
    author "司徒正美" 
    http://www.cnblogs.com/rubylouvre/ 
    */
          
          var dom = []; 
          //用于判定页面是否加载完毕 
          dom.isReady  = false; 
          //用于添加要执行的函数 
          dom.ready = function(fn){ 
            if ( dom.isReady ) { 
              fn() 
            } else { 
              dom.push( fn ); 
            } 
          } 
          //执行所有在window.onload之前放入的函数 
          dom.fireReady = function() { 
            if ( !dom.isReady ) { 
              if ( !document.body ) { 
                return setTimeout( dom.fireReady, 16 ); 
              } 
              dom.isReady = 1; 
              if ( dom.length ) { 
                for(var i = 0, fn;fn = dom[i];i++) 
                  fn() 
              } 
            } 
          } 
          //开始初始化domReady函数,判定页面的加载情况 
          if ( document.readyState === "complete" ) { 
            dom.fireReady(); 
          }else if(-[1,] ){ 
            document.addEventListener( "DOMContentLoaded", function() { 
              document.removeEventListener( "DOMContentLoaded",  arguments.callee , false ); 
              dom.fireReady(); 
            }, false ); 
          }else { 
            //当页面包含图片时,onreadystatechange事件会触发在window.onload之后, 
            //换言之,它只能正确地执行于页面不包含二进制资源或非常少或者被缓存时 
            document.attachEvent("onreadystatechange", function() { 
              if ( document.readyState == "complete" ) { 
                document.detachEvent("onreadystatechange", arguments.callee ); 
                dom.fireReady(); 
              } 
            }); 
            (function(){ 
              if ( dom.isReady ) { 
                return; 
              } 
              //doScroll存在于所有标签而不管其是否支持滚动条 
              //这里如果用document.documentElement.doScroll(),我们需要判定其是否位于顶层document 
              var node = new Image 
              try { 
                node.doScroll(); 
                node = null//防止IE内存泄漏 
              } catch( e ) { 
                //javascrpt最短时钟间隔为16ms,这里取其倍数 
                //http://blog.csdn.net/aimingoo/archive/2006/12/21/1451556.aspx 
                setTimeout( arguments.callee, 64 ); 
                return; 
              } 
              dom.fireReady(); 
            })(); 
          } 

    demo:

    View Code
     
    <!doctype html>
    <html lang="en">
      <head>
        <meta charset="utf-8" />
        <meta content="IE=8" http-equiv="X-UA-Compatible"/>
        <title>domReady by 司徒正美</title>
    
        <meta http-equiv="content-type" content="text/html;charset=UTF-8" />
        <title>domReady by 司徒正美</title>
       
        <script type="text/javascript">
               var dom = [];
          //用于判定页面是否加载完毕
          dom.isReady  = false;
          //用于添加要执行的函数
          dom.ready = function(fn){
            if ( dom.isReady ) {
              fn()
            } else {
              dom.push( fn );
            }
          }
          //执行所有在window.onload之前放入的函数
          dom.fireReady = function() {
            if ( !dom.isReady ) {
              if ( !document.body ) {
                return setTimeout( dom.fireReady, 16 );
              }
              dom.isReady = 1;
              if ( dom.length ) {
                for(var i = 0, fn;fn = dom[i];i++)
                  fn()
              }
            }
          }
          //开始初始化domReady函数,判定页面的加载情况
          if ( document.readyState === "complete" ) {
            dom.fireReady();
          }else if(-[1,] ){
            document.addEventListener( "DOMContentLoaded", function() {
              document.removeEventListener( "DOMContentLoaded",  arguments.callee , false );
              dom.fireReady();
            }, false );
          }else {
            //当页面包含图片时,onreadystatechange事件会触发在window.onload之后,
            //换言之,它只能正确地执行于页面不包含二进制资源或非常少或者被缓存时
            document.attachEvent("onreadystatechange", function() {
              if ( document.readyState == "complete" ) {
                document.detachEvent("onreadystatechange", arguments.callee );
                dom.fireReady();
              }
            });
            (function(){
              if ( dom.isReady ) {
                return;
              }
              //doScroll存在于所有标签而不管其是否支持滚动条
              //这里如果用document.documentElement.doScroll(),我们需要判定其是否位于顶层document
              var node = new Image
              try {
                node.doScroll();
                node = null//防止IE内存泄漏
              } catch( e ) {
                //javascrpt最短时钟间隔为16ms,这里取其倍数
                //http://blog.csdn.net/aimingoo/archive/2006/12/21/1451556.aspx
                setTimeout( arguments.callee, 64 );
                return;
              }
              dom.fireReady();
            })();
          }
          window.onload = function(){
            var p = document.createElement("p")
            p.innerHTML = "window.onload"
            document.body.appendChild(p);
          };
          dom.ready(function(){
            var p = document.createElement("p")
            p.innerHTML = "domReady1"
            document.body.appendChild(p);
          });
          dom.ready(function(){
            var p = document.createElement("p")
            p.innerHTML = "domReady2"
            document.body.appendChild(p);
          });
      
        
        </script>
    
      </head>
      <body>
        <h1>domReady第三版</h1>
        <p id="p"></p>
        <h1>加载图片</h1>
        <p><img src="http://images.cnblogs.com/cnblogs_com/rubylouvre/199042/o_s011.jpg"></p>
    
      </body>
    </html>

    原文链接:我的domReady第三版.司徒正美.http://www.cnblogs.com/rubylouvre/archive/2010/04/15/1712780.html

    知识共享许可协议
    作品Tim Zhang创作,采用知识共享署名 3.0 中国大陆许可协议进行许可。 。
  • 相关阅读:
    基于动态IP的Internet视频监控解决方案(作者:吴晓晖)
    Avid
    Silverlight 自定义控件的继承问题
    VOD三种VOD视频点播技术的简介和比较
    服务器主流存储:SAS存储知识问答
    获取oracle系统数据的sql
    C#去除字符串空格的几种方法
    利用Windows Media实现IP组播
    两种宽带接入方式HFC与ADSL的比较
    C#中用XMLDocument写文件时,去掉XMLNS属性
  • 原文地址:https://www.cnblogs.com/ccdc/p/2714944.html
Copyright © 2011-2022 走看看