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 相关文章推荐
javascript 模式设计之工厂模式学习心得
Apr 27 Javascript
15 个 JavaScript Web UI 库
May 19 Javascript
js获取select选中的option的text示例代码
Dec 19 Javascript
jquery实现通用版鼠标经过淡入淡出效果
Jun 15 Javascript
javascript判断并获取注册表中可信任站点的方法
Jun 01 Javascript
js图片翻书效果代码分享
Aug 20 Javascript
JavaScript数据结构之二叉树的遍历算法示例
Apr 13 Javascript
详解weex默认webpack.config.js改造
Jan 08 Javascript
Vue组件开发技巧总结
Mar 04 Javascript
详解vue-cli官方脚手架配置
Jul 20 Javascript
Vue监听数据渲染DOM完以后执行某个函数详解
Sep 11 Javascript
jQuery Ajax实现Select多级关联动态绑定数据的实例代码
Oct 26 jQuery
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
星际争霸教主Flash的ID由来:你永远不会知道他之前的ID是www!
2019/01/18 星际争霸
php实现微信原生支付(扫码支付)功能
2018/05/30 PHP
JS创建优美的页面滑动块效果 - Glider.js
2007/09/27 Javascript
JavaScript中Math对象使用说明
2008/01/16 Javascript
js+CSS 图片等比缩小并垂直居中实现代码
2008/12/01 Javascript
在网页里看flash的trace数据的js类
2009/01/10 Javascript
Google排名中的10个最著名的 JavaScript库
2010/04/27 Javascript
20条学习javascript的编程规范的建议
2014/11/28 Javascript
提交按钮的name='submit'引起的js失效问题及原因
2015/02/25 Javascript
JS+DIV实现鼠标划过切换层效果的方法
2015/05/25 Javascript
BootStrap初学者对弹出框和进度条的使用感觉
2016/06/27 Javascript
基于Vuejs实现购物车功能
2016/08/02 Javascript
jQuery ztree实现动态树形多选菜单
2016/08/12 Javascript
node.js中 stream使用教程
2016/08/28 Javascript
解析AngularJS中get请求URL出现的跨域问题
2016/12/01 Javascript
tablesorter.js表格排序使用方法(支持中文排序)
2017/02/10 Javascript
jQuery弹出窗口简单实现代码
2017/03/09 Javascript
jQuery实现的手动拖动控制进度条效果示例【测试可用】
2018/04/18 jQuery
vue-quill-editor+plupload富文本编辑器实例详解
2018/10/19 Javascript
vue router 用户登陆功能的实例代码
2019/04/24 Javascript
vue 指令和过滤器的基本使用(品牌管理案例)
2019/11/04 Javascript
Node.js path模块,获取文件后缀名操作
2020/11/07 Javascript
使用Django的模版来配合字符串翻译工作
2015/07/27 Python
对python插入数据库和生成插入sql的示例讲解
2018/11/14 Python
python定时按日期备份MySQL数据并压缩
2019/04/19 Python
Python使用MyQR制作专属动态彩色二维码功能
2019/06/04 Python
Django中的cookie和session
2019/08/27 Python
Python如何合并多个字典或映射
2020/07/24 Python
简历里的自我评价
2014/01/31 职场文书
反腐倡廉警示教育活动心得体会
2014/09/04 职场文书
对外汉语专业大学生职业生涯规划范文
2014/09/13 职场文书
公司与个人合作协议书
2016/03/19 职场文书
创业计划书之物流运送
2019/09/17 职场文书
教你用eclipse连接mysql数据库
2021/04/22 MySQL
nginx容器方式反向代理实战
2022/04/18 Servers
win10如何更改appdata文件夹的默认位置?
2022/07/15 数码科技