zoukankan      html  css  js  c++  java
  • jQuery源码分析之ready方法

      1 var //......代码省略
      2        //事件回调函数列表对象
      3         //为了便于解释暂且称之为ready事件回调函数列表对象,
      4         //当然DOM事件模型是没有所谓的ready事件的哦。
      5         readyList
      6         //......代码省略
      7  ;
      8 jQuery.fn = jQuery.prototype = {
      9     //......代码省略
     10     ready: function( fn ) {
     11         // Attach the listeners
     12         // 绑定ready事件监听器,DOM标准里是无所谓ready事件,
     13         // 这里只是自己起的为了方便分析代码
     14         jQuery.bindReady();
     15         // Add the callback
     16         // 添加回调函数到回调函数列表中
     17         readyList.add( fn );
     18         return this;
     19     },
     20     //......代码省略
     21 };
     22 jQuery.extend({
     23     //......代码省略
     24     // Is the DOM ready to be used? Set to true once it occurs.
     25     // 标识页面DOM元素是否已加载完毕
     26     isReady: false,
     27     // A counter to track how many items to wait for before
     28     // the ready event fires. See #6781
     29     readyWait: 1,
     30     // Hold (or release) the ready event
     31     holdReady: function( hold ) {
     32         if ( hold ) {
     33             jQuery.readyWait++;
     34         } else {
     35             jQuery.ready( true );
     36         }
     37     },
     38     // Handle when the DOM is ready
     39     ready: function( wait ) {
     40         // Either a released hold or an DOMready/load event and not yet ready
     41         if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) {
     42             // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
     43             if ( !document.body ) {
     44                 return setTimeout( jQuery.ready, 1 );
     45             }
     46             // Remember that the DOM is ready
     47             jQuery.isReady = true;
     48             // If a normal DOM Ready event fired, decrement, and wait if need be
     49             if ( wait !== true && --jQuery.readyWait > 0 ) {
     50                 return;
     51             }
     52             // If there are functions bound, to execute
     53             readyList.fireWith( document, [ jQuery ] );
     54             // Trigger any bound ready events
     55             if ( jQuery.fn.trigger ) {
     56                 jQuery( document ).trigger( "ready" ).off( "ready" );
     57             }
     58         }
     59     },
     60     bindReady: function() {
     61         //判断ready事件回调函数列表是否已初始化
     62         if ( readyList ) {
     63             //如是则返回
     64             return;
     65         }
     66         //创建ready事件回调函数列表对象
     67         //这里调用jQuery.Callbacks方法,
     68         //Callbacks的作用在上篇已说过,不再赘述
     69         readyList = jQuery.Callbacks( "once memory" );
     70         // Catch cases where $(document).ready() is called after the
     71         // browser event has already occurred.
     72         // 判断页面DOM元素是否已加载完毕
     73         if ( document.readyState === "complete" ) {
     74             // Handle it asynchronously to allow scripts the opportunity to delay ready
     75             // 如是则异步执行jQuery.ready方法
     76             // 调用setTimeout目的是异步执行jQuery.ready方法
     77             return setTimeout( jQuery.ready, 1 );
     78         }
     79         // Mozilla, Opera and webkit nightlies currently support this event
     80         // 支持W3C DOM标准的浏览器则用addEventListener绑定
     81         if ( document.addEventListener ) {
     82             // Use the handy event callback
     83             // 支持W3C DOM标准的浏览器一般是支持DOMContentLoaded事件
     84             // DOMContentLoaded是页面的DOM元素(仅仅只是DOM元素)全部加载完毕后触发
     85             document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
     86             // A fallback to window.onload, that will always work
     87             // 当然有些所谓支持W3C DOM标准的浏览器可能不支持DOMContentLoaded事件,
     88             // 为了不被坑爹,在此得留一手,为确保万无一失,再绑定window的load事件,
     89             // 因为window的load事件是所有浏览器都支持的,页面载入完成后是肯定会触发。
     90             // 在这里说明一下DOMContentLoaded和load事件的区别:
     91             // DOMContentLoaded事件是只要页面DOM元素全部加载完毕即触发
     92             // window的load事件是页面的所有DOM元素以及全部资源(如图片/flash)加载完毕即触发
     93             // 理论上,DOMContentLoaded要比window的load事件先触发
     94             window.addEventListener( "load", jQuery.ready, false );
     95         } 
     96         // If IE event model is used
     97         // 针对IE浏览器用attachEvent绑定事件
     98         // 题外话:IE遵循自己的一套DOM事件模型,与W3C DOM事件模型有很大不同
     99         // 故需特殊对待
    100         else if ( document.attachEvent ) {
    101             // ensure firing before onload,
    102             // maybe late but safe also for iframes
    103             // IE不支持DOMContentLoaded事件,但可使用onreadystatechange事件替代之
    104             document.attachEvent( "onreadystatechange", DOMContentLoaded );
    105             // A fallback to window.onload, that will always work
    106             // 为了避免被onreadystatechange事件坑爹,需留一手,
    107             // 绑定window的onload事件,这是页面载入完成后一定会触发的。
    108             window.attachEvent( "onload", jQuery.ready );
    109             // If IE and not a frame
    110             // continually check to see if the document is ready
    111             var toplevel = false;
    112             try {
    113                 //使用window.frameElement判断是否是顶级页面
    114                 toplevel = window.frameElement == null;
    115             } catch(e) {
    116                 //抛异常,则当做不是顶级页面处理
    117             }
    118             //document.documentElement.doScroll
    119             //IE独有方法,模拟用户滚动条点击;
    120             //用此法判断IE下的DOM元素是否加载完成
    121             if ( document.documentElement.doScroll && toplevel ) {
    122                 doScrollCheck();
    123             }
    124         }
    125     }
    126 //......代码省略
    127 });
    128 //.....代码省略
    129 // The DOM ready check for Internet Explorer
    130 // 检测IE浏览器下的DOM元素是否加载完成
    131 function doScrollCheck() {
    132     //判断页面是否已加载完毕
    133     //如是则无需再执行下面的检测代码
    134     if ( jQuery.isReady ) {
    135         return;
    136     }
    137     // 执行document.documentElement.doScroll方法
    138     // 若抛异常,表示IE的DOM元素未加载完毕,则继续异步执行doScrollCheck检测
    139     // 若不抛异常,表示IE的DOM元素加载完成,则将执行jQuery.ready方法
    140     try {
    141         // If IE is used, use the trick by Diego Perini
    142         // http://javascript.nwbox.com/IEContentLoaded/
    143         document.documentElement.doScroll("left");
    144     } catch(e) {
    145         setTimeout( doScrollCheck, 1 );
    146         return;
    147     }
    148     // and execute any waiting functions
    149     // IE的DOM元素加载完成调用jQuery.ready方法
    150     jQuery.ready();
    151 }
    152 //.....代码省略
    153 // Cleanup functions for the document ready method
    154 //支持W3C DOM标准浏览器
    155 if ( document.addEventListener ) {
    156     //DOMContentLoaded事件回调函数实现
    157   DOMContentLoaded = function() {
    158        //移除DOMContentLoaded事件绑定
    159     document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
    160     jQuery.ready();
    161   };
    162 } 
    163 //支持微软DOM标准浏览器
    164 else if ( document.attachEvent ) {
    165     //onreadystatechange事件回调函数实现
    166   DOMContentLoaded = function() {
    167     // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
    168     if ( document.readyState === "complete" ) {
    169             //移除onreadystatechange事件绑定
    170        document.detachEvent( "onreadystatechange", DOMContentLoaded );
    171         jQuery.ready();
    172     }
    173   };
    174 }
    175 //.....代码省略
  • 相关阅读:
    String类之indexOf--->查找某字对应的位置
    5、文件过滤器
    String类之endsWith方法--->检测该字符串以xx为结尾
    for循环
    java-成员方法/变量、类方法/变量等区别
    4、File类之获取方法
    3、File类之创建、删除、重命名、判断方法
    2、创建File类对象
    Java 实现Redis客户端,服务端
    Phoenix踩坑填坑记录
  • 原文地址:https://www.cnblogs.com/bender/p/3361146.html
Copyright © 2011-2022 走看看