jQuery的ready方法实现原理分析


Posted in Javascript onOctober 26, 2016

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 相关文章推荐
动态修改DOM 里面的 id 属性的弊端分析
Sep 03 Javascript
清除网页历史记录,屏蔽后退按钮!
Dec 22 Javascript
JavaScript中innerHTML,innerText,outerHTML的用法及区别
Sep 01 Javascript
jQuery满屏焦点图左右滚动特效代码分享
Sep 07 Javascript
jQuery增加和删除表格项目及实现表格项目排序的方法
May 30 Javascript
创建基于Bootstrap的下拉菜单的DropDownList的JQuery插件
Jun 02 Javascript
概述一个页面从输入URL到页面加载完的过程
Dec 16 Javascript
Vue 中mixin 的用法详解
Apr 23 Javascript
详解小程序退出页面时清除定时器
Apr 28 Javascript
Vue实现数据表格合并列rowspan效果
Nov 30 Javascript
JavaScript实现多层颜色选项卡嵌套
Sep 21 Javascript
如何使用JavaScript策略模式校验表单
Apr 29 Javascript
JavaScript中省略元素对数组长度的影响
Oct 26 #Javascript
BootStrap tab选项卡使用小结
Aug 09 #Javascript
Bootstrap按钮功能之查询按钮和重置按钮
Oct 26 #Javascript
AngularJS中如何使用echart插件示例详解
Oct 26 #Javascript
BootStrap modal模态弹窗使用小结
Oct 26 #Javascript
BootStrap实现带有增删改查功能的表格(DEMO详解)
Oct 26 #Javascript
BootStrap tooltip提示框使用小结
Oct 26 #Javascript
You might like
php学习笔记 php中面向对象三大特性之一[封装性]的应用
2011/06/13 PHP
PHP使用curl模拟post上传及接收文件的方法
2016/03/04 PHP
学习PHP的数组总结【经验】
2016/05/05 PHP
JavaScript中的其他对象
2008/01/16 Javascript
让IE6支持min-width和max-width的方法
2010/06/25 Javascript
iframe的onload在Chrome/Opera中执行两次Bug的解决方法
2011/03/17 Javascript
JQuery插件开发示例代码
2013/11/06 Javascript
javascript设置金额样式转换保留两位小数示例代码
2013/12/04 Javascript
JQuery页面的表格数据的增加与分页的实现
2013/12/10 Javascript
Javascript中的Callback方法浅析
2015/03/15 Javascript
js实现的二级横向菜单条实例
2015/08/22 Javascript
原生JS实现风箱式demo,并封装了一个运动框架(实例代码)
2016/07/22 Javascript
使用ajaxfileupload.js实现上传文件功能
2016/08/13 Javascript
js简单正则验证汉字英文及下划线的方法
2016/11/28 Javascript
AngularJS入门教程之Helloworld示例
2016/12/25 Javascript
Bootstrap模态框案例解析
2017/03/05 Javascript
基于redis的小程序登录实现方法流程分析
2020/05/25 Javascript
[01:08]2014DOTA2展望TI 剑指西雅图LGD战队专访
2014/06/30 DOTA
[01:02:00]DOTA2-DPC中国联赛 正赛 Elephant vs IG BO3 第三场 1月24日
2021/03/11 DOTA
Python中的多重装饰器
2015/04/11 Python
Python3中使用urllib的方法详解(header,代理,超时,认证,异常处理)
2016/09/21 Python
python实现二维码扫码自动登录淘宝
2016/12/27 Python
Python编程实现微信企业号文本消息推送功能示例
2017/08/21 Python
python实现简单的单变量线性回归方法
2018/11/08 Python
详解python tkinter教程-事件绑定
2019/03/28 Python
如何通过50行Python代码获取公众号全部文章
2019/07/12 Python
python3图片文件批量重命名处理
2019/10/31 Python
浅谈keras.callbacks设置模型保存策略
2020/06/18 Python
HTML5引入的新数组TypedArray介绍
2012/12/24 HTML / CSS
资生堂英国官网:Shiseido英国
2020/12/30 全球购物
求网格中的黑点分布
2013/11/06 面试题
开业主持词
2014/03/21 职场文书
小学二年级评语
2014/04/21 职场文书
社会心理学学习心得体会
2016/01/22 职场文书
教学工作总结范文5篇
2019/08/19 职场文书
golang 比较浮点数的大小方式
2021/05/02 Golang