jQuery  ready方法实现原理详解


Posted in Javascript onOctober 19, 2016

今天闲来无事研究研究jQuery.ready()的内部实现,看JQ的源码一头雾水,由于自己很菜了,于是翻了翻牛人的播客,讲述详细,收获颇多。

先普及一下jquery.ready()和window.onload,window.onload事件是在页面所有的资源都加载完毕后触发的. 如果页面上有大图片等资源响应缓慢, 会导致window.onload事件迟迟无法触发.所以出现了DOM Ready事件. 此事件在DOM文档结构准备完毕后触发, 即在资源加载前触发. 

jQuery中的ready方法实现了当页面加载完成后才执行的效果,但他并不是window.onload或者doucment.onload的封装,而是使用 标准W3C浏览器DOM隐藏api和IE浏览器缺陷来完成的,首先,我们来看jQuery的代码

DOMContentLoaded = function()
 {
  //取消事件监听,执行ready方法
 if ( document.addEventListener )
 {   
  document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
  jQuery.ready();
 }
  else if ( document.readyState === "complete" ) 
 {
  document.detachEvent( "onreadystatechange", DOMContentLoaded );
  jQuery.ready();
 }
};
jQuery.ready.promise = function( obj ) {
 if ( !readyList ) {

  readyList = jQuery.Deferred();
   //表示页面已经加载完成,直接调用 ready方法
  if ( document.readyState === "complete" ) { 
   //将 jQuery.ready压入异步消息队列,设置延迟时间1毫秒(注意,有些浏览器延迟不能小于4毫秒)
   setTimeout( jQuery.ready); 
  } 
  else if ( document.addEventListener ) //
  {
    //监听DOM加载完成
   document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
    //这里是为了确保所有ready执行结束,如果DOMContentLoaded方法执行了,将有一个状态值 isReady被设置为true,因此,
    //ready方法一旦执行,那么将只执行一次,window.addEventListener中的ready 将被 return 中断
   window.addEventListener( "load", jQuery.ready, false );
 
  } else {
   //低版本的IE浏览器
   document.attachEvent( "onreadystatechange", DOMContentLoaded );
   window.attachEvent( "onload", jQuery.ready );

   var top = false;

   try {
    top = window.frameElement == null && document.documentElement;
   } catch(e) {}

   if ( top && top.doScroll ) //剔除iframe的成分
   {
    (function doScrollCheck() {
     if ( !jQuery.isReady ) {

      try {
       //根据bug来兼容低版本的IE http://javascript.nwbox.com/IEContentLoaded/
       top.doScroll("left");
      } catch(e) {
       //由于低版本的IE 浏览器,onreadystatechange事件不可靠,因此需要根据各个bug来判断页面是否已加载完成
       return setTimeout( doScrollCheck, 50 ); 
      }

      jQuery.ready();
     }
    })();
   }
  }
 }
 return readyList.promise( obj );
};
ready: function( wait )
 {

 if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { 
  //判断页面是否已完成加载并且是否已经执行ready方法
  return;
 }


 if ( !document.body ) {
  return setTimeout( jQuery.ready );
 }

  
 jQuery.isReady = true; //指示ready方法已被执行

  
 if ( wait !== true && --jQuery.readyWait > 0 ) {
  return;
 }

  
 readyList.resolveWith( document, [ jQuery ] );

  
 if ( jQuery.fn.trigger ) {
  jQuery( document ).trigger("ready").off("ready"); 
 }
},

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

Javascript 相关文章推荐
数组Array进行原型prototype扩展后带来的for in遍历问题
Feb 07 Javascript
jQuery 顶部导航跟随滚动条滚动固定浮动在顶部
Jun 06 Javascript
jQuery中:enabled选择器用法实例
Jan 04 Javascript
jQuery中noConflict()用法实例分析
Feb 08 Javascript
PHP+jQuery+Ajax+Mysql如何实现发表心情功能
Aug 06 Javascript
学习JavaScript正则表达式
Nov 13 Javascript
jQuery插件扩展实例【添加回调函数】
Nov 26 Javascript
vue组件父子间通信之综合练习(聊天室)
Nov 07 Javascript
ReactNative之FlatList的具体使用方法
Nov 29 Javascript
d3.js实现图形缩放平移
Dec 19 Javascript
JavaScript实时更新当前的时间的示例代码
Jul 15 Javascript
jquery实现拖拽添加元素功能
Dec 01 jQuery
Javascript实现汉字和拼音互转的终极方案
Oct 19 #Javascript
Javascript typeof与instanceof的区别
Oct 18 #Javascript
javascript self对象使用详解
Oct 18 #Javascript
jQuery动态添加与删除tr行实例代码
Oct 18 #Javascript
Jquery表单验证失败后不提交的解决方法
Oct 18 #Javascript
vue.js 表格分页ajax 异步加载数据
Oct 18 #Javascript
vue.js表格分页示例
Oct 18 #Javascript
You might like
最贵的咖啡是怎么产生的,它的风味怎么样?
2021/03/04 新手入门
使用session判断用户登录用户权限(超简单)
2013/06/08 PHP
php中的filesystem文件系统函数介绍及使用示例
2014/02/13 PHP
php在数组中查找指定值的方法
2015/03/17 PHP
PHP file_get_contents函数读取远程数据超时的解决方法
2015/05/13 PHP
PHP面向对象程序设计之命名空间与自动加载类详解
2016/12/02 PHP
laravel Model 执行事务的实现
2019/10/10 PHP
laravel5.6框架操作数据curd写法(查询构建器)实例分析
2020/01/26 PHP
用Javascript评估用户输入密码的强度实现代码
2011/11/30 Javascript
js判断浏览器类型为ie6时不执行
2014/06/15 Javascript
轻松实现jquery手风琴效果
2016/01/14 Javascript
JavaScript设计模式开发中组合模式的使用教程
2016/05/18 Javascript
jquery实现文本框的禁用和启用
2016/12/07 Javascript
微信小程序 tabs选项卡效果的实现
2017/01/05 Javascript
常用的js方法合集
2017/03/10 Javascript
深入理解JavaScript 中的匿名函数((function() {})();)与变量的作用域
2018/08/28 Javascript
[42:32]完美世界DOTA2联赛循环赛 Magma vs PXG BO2第二场 10.28
2020/10/28 DOTA
Python3下错误AttributeError: ‘dict’ object has no attribute’iteritems‘的分析与解决
2017/07/06 Python
python实现电脑自动关机
2018/06/20 Python
利用Python半自动化生成Nessus报告的方法
2019/03/19 Python
python实现爬山算法的思路详解
2019/04/09 Python
节日快乐! Python画一棵圣诞树送给你
2019/12/24 Python
浅谈Python中文件夹和python package包的区别
2020/06/01 Python
CAT鞋英国官网:坚固耐用的靴子和鞋
2016/10/21 全球购物
Charlotte Tilbury美国官网:英国美妆品牌
2017/10/13 全球购物
澳洲小众品牌的集合网站:BNKR
2018/02/23 全球购物
Harrods美国:英国最大的百货公司
2018/11/04 全球购物
几道数据库的概念性面试题
2014/05/30 面试题
同步和异步有何异同,在什么情况下分别使用他们
2013/04/09 面试题
致裁判员加油稿
2014/02/08 职场文书
妇联主席先进事迹
2014/05/18 职场文书
500字小学生检讨书
2015/02/19 职场文书
2015年教师个人业务工作总结
2015/10/23 职场文书
拔河比赛队名及霸气口号
2015/12/24 职场文书
2016年共产党员个人承诺书
2016/03/24 职场文书
go语言求任意类型切片的长度操作
2021/04/26 Golang