zoukankan      html  css  js  c++  java
  • 我的domReady第三版

    新的版本放弃使用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();
            })();
          }
       
    

  • 相关阅读:
    更新证书错误Code Sign error: Provisioning profile ‘XXXX'can't be found
    解决Xcode 5下使用SVN出现 The operation couldn’t be completed. (NSURLErrorDomain error -1012.) 问题
    Android模拟器启动不了解决办法
    在AndroidManifest.xml文件中设置Android程序的启动界面方法
    Windows2008+MyEclipse10+Android开发环境搭配
    ADT下载地址整理
    android:inputType常用取值
    VS2010中使用Jquery调用Wcf服务读取数据库记录
    Linux手动安装netcore3.0
    StdOS之运行指示灯
  • 原文地址:https://www.cnblogs.com/rubylouvre/p/1712780.html
Copyright © 2011-2022 走看看