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 相关文章推荐
ASP.NET jQuery 实例2 (表单中使用回车在TextBox之间向下移动)
Jan 13 Javascript
PHP开发者必须掌握的6个关键字
Apr 14 Javascript
jQuery+css实现百度百科的页面导航效果
Dec 16 Javascript
CKEditor无法验证的解决方案(js验证+jQuery Validate验证)
May 09 Javascript
js通过classname来获取元素的方法
Nov 24 Javascript
利用Bootstrap实现表格复选框checkbox全选
Dec 21 Javascript
Bootstrap3 内联单选和多选框
Dec 29 Javascript
浅析javaScript中的浅拷贝和深拷贝
Feb 15 Javascript
JS实现给json数组动态赋值的方法示例
Mar 19 Javascript
使用MUI框架模拟手机端的下拉刷新和上拉加载功能
Sep 04 Javascript
js Array.slice的8种不同用法示例
Jul 10 Javascript
vue使用echarts画组织结构图
Feb 06 Vue.js
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 各种应用乱码问题的解决方法
2010/05/09 PHP
phpExcel导出大量数据出现内存溢出错误的解决方法
2013/02/28 PHP
使用PHP会话(Session)实现用户登陆功能
2013/06/29 PHP
Zend Framework实现多服务器共享SESSION数据的方法
2016/03/22 PHP
php可变长参数处理函数详解
2017/02/22 PHP
对new functionName()定义一个函数的理解
2014/05/22 Javascript
JavaScript中的this,call,apply使用及区别详解
2016/01/29 Javascript
Bootstrap每天必学之附加导航(Affix)插件
2016/04/25 Javascript
JQuery EasyUI Layout 在from布局自适应窗口大小的实现方法
2016/05/28 Javascript
【经典源码收藏】jQuery实用代码片段(筛选,搜索,样式,清除默认值,多选等)
2016/06/07 Javascript
javascript验证内容为数字以及长度为10的简单实例
2016/08/20 Javascript
Vue.js 和 MVVM 的注意事项
2016/11/07 Javascript
使用JS实现气泡跟随鼠标移动的动画效果
2017/09/16 Javascript
JS 实现缓存算法的示例(FIFO/LRU)
2018/03/20 Javascript
vue使用echarts图表的详细方法
2018/10/22 Javascript
nodejs提示:cross-device link not permitted, rename错误的解决方法
2019/06/10 NodeJs
Vue-cli3.x + axios 跨域方案踩坑指北
2019/07/04 Javascript
Vue调用后端java接口的实例代码
2019/10/28 Javascript
vue中解决微信html5原生ios虚拟键返回不刷新问题
2020/10/20 Javascript
python获取本机外网ip的方法
2015/04/15 Python
Django中几种重定向方法
2015/04/28 Python
详解python之多进程和进程池(Processing库)
2017/06/09 Python
python实现决策树分类(2)
2018/08/30 Python
python自动保存百度盘资源到百度盘中的实例代码
2019/08/26 Python
Pandas聚合运算和分组运算的实现示例
2019/10/17 Python
Django静态资源部署404问题解决方案
2020/05/11 Python
pycharm-professional-2020.1下载与激活的教程
2020/09/21 Python
Maison Lab荷兰:名牌Outlet购物
2018/08/10 全球购物
Ivory Isle Designs美国/加拿大:婚礼和活动文具公司
2018/08/21 全球购物
laravel使用redis队列实例讲解
2021/03/23 PHP
教学实习自我评价
2014/01/28 职场文书
菜篮子工程实施方案
2014/03/08 职场文书
党员个人年度总结
2015/02/14 职场文书
繁星春水读书笔记
2015/06/30 职场文书
Python基础之数据类型知识汇总
2021/05/18 Python
xhunter1.sys可以删除嘛? win11提示xhunter1.sys驱动不兼容解决办法
2022/09/23 数码科技