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 相关文章推荐
jquery ajax return没有返回值的解决方法
Oct 20 Javascript
jquery ajax跨域解决方法(json方式)
Feb 04 Javascript
js动态移动滚动条至底部示例代码
Apr 24 Javascript
将form表单中的元素转换成对象的方法适用表单提交
May 02 Javascript
node.js中的fs.appendFileSync方法使用说明
Dec 17 Javascript
JavaScript使用键盘输入控制实现数字验证功能
Aug 19 Javascript
jQuery实现的图片轮播效果完整示例
Sep 12 Javascript
微信小程序 Audio API详解及实例代码
Sep 30 Javascript
Vue.js开发环境搭建
Nov 10 Javascript
AngularJS中使用ngModal模态框实例
May 27 Javascript
JS跨域请求的问题解析
Dec 03 Javascript
Vue实现点击导航栏当前标签后变色功能
Aug 19 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 正则表达式小结
2009/08/31 PHP
php使用str_replace实现输入框回车替换br的方法
2014/11/24 PHP
静态页面下用javascript操作ACCESS数据库(读增改删)的代码
2007/05/14 Javascript
xheditor与validate插件冲突的解决方案
2010/04/15 Javascript
深入浅析jQuery对象$.html
2016/08/22 Javascript
JavaScript中数组Array.sort()排序方法详解
2017/03/01 Javascript
Angular.JS中的指令引用template与指令当做属性详解
2017/03/30 Javascript
Angular.js中window.onload(),$(document).ready()的写法浅析
2017/09/28 Javascript
详解Angular5 服务端渲染实战
2018/01/04 Javascript
浅谈redux以及react-redux简单实现
2018/08/28 Javascript
Vue服务端渲染实践之Web应用首屏耗时最优化方案
2019/03/22 Javascript
Element Cascader 级联选择器的使用示例
2020/07/27 Javascript
Python类的基础入门知识
2008/11/24 Python
python获取程序执行文件路径的方法(推荐)
2018/04/26 Python
python使用matplotlib绘制热图
2018/11/07 Python
python lxml中etree的简单应用
2019/05/10 Python
PyQt5 多窗口连接实例
2019/06/19 Python
Python及Pycharm安装方法图文教程
2019/08/05 Python
python读写csv文件的方法
2019/08/13 Python
使用 Supervisor 监控 Python3 进程方式
2019/12/05 Python
为什么黑客都用python(123个黑客必备的Python工具)
2020/01/31 Python
Jupyter Notebook打开任意文件夹操作
2020/04/14 Python
python 实现两个npy档案合并
2020/07/01 Python
python制作微博图片爬取工具
2021/01/16 Python
HTML5拖拉上传文件的简单实例
2017/01/11 HTML / CSS
静态成员和非静态成员的区别
2012/05/12 面试题
Final类有什么特点
2012/04/25 面试题
美术专业学生个人自我评价
2013/09/19 职场文书
英语自荐信常用语句
2013/12/13 职场文书
本科毕业生求职自荐信
2014/02/03 职场文书
驾驶员培训方案
2014/05/01 职场文书
2014卖家双十一活动策划书
2014/09/29 职场文书
2015年班级工作总结范文
2015/04/03 职场文书
Nginx 根据URL带的参数转发的实现
2021/04/01 Servers
DSP接收机前端设想
2022/04/05 无线电
python使用shell脚本创建kafka连接器
2022/04/29 Python