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 相关文章推荐
jquery实现弹出窗口效果的实例代码
Nov 28 Javascript
js 加密压缩出现bug解决方案
Nov 25 Javascript
JavaScript原生对象之Date对象的属性和方法详解
Mar 13 Javascript
分享9个最好用的JavaScript开发工具和代码编辑器
Mar 24 Javascript
jQuery实现的Tab滑动选项卡及图片切换(多种效果)小结
Sep 14 Javascript
jQuery仅用3行代码实现的显示与隐藏功能完整实例
Oct 08 Javascript
Node.js使用Express创建Web项目详细教程
Mar 31 Javascript
IScroll那些事_当内容不足时下拉刷新的解决方法
Jul 18 Javascript
详解mpvue小程序中怎么引入iconfont字体图标
Oct 01 Javascript
在Chrome DevTools中调试JavaScript的实现
Apr 07 Javascript
js实现页面导航层级指示效果
Aug 25 Javascript
JavaScript手写数组的常用函数总结
Nov 22 Javascript
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
PHP实现用户认证及管理完全源码
2007/03/11 PHP
php另类上传图片的方法(PHP用Socket上传图片)
2013/10/30 PHP
Laravel中使用自己编写类库的3种方法
2015/02/10 PHP
高质量PHP代码的50个实用技巧必备(下)
2016/01/22 PHP
AES加解密在php接口请求过程中的应用示例
2016/10/26 PHP
PHP Swoole异步读取、写入文件操作示例
2019/10/24 PHP
简洁短小的 JavaScript IE 浏览器判定代码
2010/03/21 Javascript
JS左右无缝滚动(一般方法+面向对象方法)
2012/08/17 Javascript
js实现省市联动效果的简单实例
2014/02/10 Javascript
js动态修改整个页面样式达到换肤效果
2014/05/23 Javascript
innerHTML中标签可以换行的方法汇总
2015/08/14 Javascript
jQuery Mobile开发中日期插件Mobiscroll使用说明
2016/03/02 Javascript
js获取元素的外链样式的简单实现方法
2016/06/06 Javascript
vue.js指令和组件详细介绍及实例
2017/04/06 Javascript
jquery如何实现点击空白处隐藏元素
2017/12/05 jQuery
详解Nodejs内存治理
2018/05/13 NodeJs
微信小程序实现自动定位功能
2018/10/31 Javascript
Python实现获取照片拍摄日期并重命名的方法
2017/09/30 Python
python 除法保留两位小数点的方法
2018/07/16 Python
Python 读写文件的操作代码
2018/09/20 Python
python3转换code128条形码的方法
2019/04/17 Python
tensorflow实现tensor中满足某一条件的数值取出组成新的tensor
2020/01/04 Python
使用Python求解带约束的最优化问题详解
2020/02/11 Python
python如何停止递归
2020/09/09 Python
CSS3弹性伸缩布局之box布局
2016/07/12 HTML / CSS
YesStyle美国/全球:购买亚洲时装、美容化妆品和生活百货
2017/01/16 全球购物
中国跨境电商:Tomtop
2017/03/16 全球购物
给定一个时间点,希望得到其他时间点
2013/11/07 面试题
财务人员担保书
2014/05/13 职场文书
体育口号大全
2014/06/18 职场文书
感情真挚的毕业生求职信
2014/07/19 职场文书
七一建党日演讲稿
2014/09/05 职场文书
学生违纪检讨书200字
2014/10/21 职场文书
2014年幼儿园园长工作总结
2014/12/17 职场文书
如何写好闭幕词
2019/04/02 职场文书
CSS 文字装饰 text-decoration & text-emphasis 详解
2021/04/06 HTML / CSS