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 select操作的日期联动实现代码
Dec 06 Javascript
用jQuery模拟页面加载进度条的实现代码
Dec 19 Javascript
json数据的列循环示例
Sep 06 Javascript
js数组去重的5种算法实现
Nov 04 Javascript
jQuery Mobile框架中的表单组件基础使用教程
May 17 Javascript
vue.js开发实现全局调用的MessageBox组件实例代码
Nov 22 Javascript
微信小程序实现图片上传功能
May 28 Javascript
重学JS 系列:聊聊继承(推荐)
Apr 11 Javascript
微信小程序云开发之新手环境配置
May 16 Javascript
Vue 实现输入框新增搜索历史记录功能
Oct 15 Javascript
node 版本切换的实现
Feb 02 Javascript
解决vue与node模版引擎的渲染标记{{}}(双花括号)冲突问题
Sep 11 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对字符串的递增运算分析
2010/08/08 PHP
php过滤敏感词的示例
2014/03/31 PHP
EasySlider 基于jQuery功能强大简单易用的滑动门插件
2010/06/11 Javascript
用js实现输入提示(自动完成)的实例代码
2013/06/14 Javascript
禁止选中文字兼容IE、Chrome、FF等
2013/09/04 Javascript
js去除输入框中所有的空格和禁止输入空格的方法
2014/06/09 Javascript
js数组的基本操作(很全自己整理的)
2014/10/16 Javascript
jquery计算鼠标和指定元素之间距离的方法
2015/06/26 Javascript
详解Node.js包的工程目录与NPM包管理器的使用
2016/02/16 Javascript
JavaScript必知必会(二) null 和undefined
2016/06/08 Javascript
Javascript this 函数深入详解
2016/12/13 Javascript
Bootstrap进度条学习使用
2017/02/09 Javascript
jQuery.Sumoselect插件实现下拉复选框效果
2017/11/09 jQuery
深入浅析Vue.js中 computed和methods不同机制
2018/03/22 Javascript
实例分析vue循环列表动态数据的处理方法
2018/09/28 Javascript
基于AngularJS拖拽插件ngDraggable.js实现拖拽排序功能
2019/04/02 Javascript
go语言计算两个时间的时间差方法
2015/03/13 Python
在python里协程使用同步锁Lock的实例
2019/02/19 Python
将Python字符串生成PDF的实例代码详解
2019/05/17 Python
python自动生成model文件过程详解
2019/11/02 Python
Spring http服务远程调用实现过程解析
2020/06/11 Python
详解python tkinter包获取本地绝对路径(以获取图片并展示)
2020/09/04 Python
英国羊绒服装购物网站:Pure Collection
2018/10/22 全球购物
Yahoo-PHP面试题4
2012/05/05 面试题
大课间活动制度
2014/01/18 职场文书
《花瓣飘香》教学反思
2014/04/15 职场文书
团队精神的演讲稿
2014/05/14 职场文书
信用社主任竞聘演讲稿
2014/05/23 职场文书
中专生自荐信
2014/06/25 职场文书
党的群众路线教育实践活动组织生活会发言材料
2014/10/17 职场文书
党的群众路线学习笔记
2014/11/06 职场文书
2014小学语文教师个人工作总结
2014/12/03 职场文书
2015年教师自我评价范文
2015/03/04 职场文书
解决Maven项目中 Invalid bound statement 无效的绑定问题
2021/06/15 Java/Android
Springboot/Springcloud项目集成redis进行存取的过程解析
2021/12/04 Redis
java代码实现空间切割
2022/01/18 Java/Android