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 //.....代码省略
  • 相关阅读:
    Candy leetcode java
    Trapping Rain Water leetcode java
    Best Time to Buy and Sell Stock III leetcode java
    Best Time to Buy and Sell Stock II leetcode java
    Best Time to Buy and Sell Stock leetcode java
    Maximum Subarray leetcode java
    Word Break II leetcode java
    Word Break leetcode java
    Anagrams leetcode java
    Clone Graph leetcode java(DFS and BFS 基础)
  • 原文地址:https://www.cnblogs.com/bender/p/3361146.html
Copyright © 2011-2022 走看看