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 相关文章推荐
[Web]防止用户复制页面内容和另存页面的方法
Feb 06 Javascript
jQuery bind事件使用详解
May 05 Javascript
Array.prototype.concat不是通用方法反驳[译]
Sep 20 Javascript
js简单实现HTML标签Select联动带跳转
Oct 23 Javascript
js,jquery滚动/跳转页面到指定位置的实现思路
Jun 03 Javascript
javascript制作的cookie封装及使用指南
Jan 02 Javascript
js游戏人物上下左右跑步效果代码分享
Aug 28 Javascript
jQuery ajax提交Form表单实例(附demo源码)
Apr 06 Javascript
JS+HTML5实现的前端购物车功能插件实例【附demo源码下载】
Oct 17 Javascript
vue服务端渲染的实例代码
Aug 28 Javascript
Vue.js中该如何自己维护路由跳转记录
May 19 Javascript
基于vue和bootstrap实现简单留言板功能
May 30 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
xajax写的留言本
2006/11/25 PHP
分割GBK中文遭遇乱码的解决方法
2013/08/09 PHP
利用谷歌 Translate API制作自己的翻译脚本
2014/06/04 PHP
WordPress开发中自定义菜单的相关PHP函数使用简介
2016/01/05 PHP
jQuery在vs2008及js文件中的无智能提示的解决方法
2010/12/30 Javascript
5款JavaScript代码压缩工具推荐
2014/07/07 Javascript
node.js中的fs.rmdir方法使用说明
2014/12/16 Javascript
jQuery实现鼠标经过时出现隐藏层文字链接的方法
2015/10/12 Javascript
jQuery实现的网页右下角tab样式在线客服效果代码
2015/10/23 Javascript
jQuery选择器用法实例详解
2015/12/17 Javascript
jquery判断iPhone、Android设备类型
2016/09/14 Javascript
JS动态计算移动端rem的解决方案
2016/10/14 Javascript
微信小程序 新建登录页并实现tabBar隐藏
2017/06/13 Javascript
React中使用async validator进行表单验证的实例代码
2018/08/17 Javascript
Spring boot 和Vue开发中CORS跨域问题解决
2018/09/05 Javascript
使用vue实现一个电子签名组件的示例代码
2020/01/06 Javascript
原生js canvas实现鼠标跟随效果
2020/08/02 Javascript
Python动态加载模块的3种方法
2014/11/22 Python
详解python 3.6 安装json 模块(simplejson)
2019/04/02 Python
Python爬虫库requests获取响应内容、响应状态码、响应头
2020/01/25 Python
将数据集制作成VOC数据集格式的实例
2020/02/17 Python
python获取栅格点和面值的实现
2020/03/10 Python
详解python中GPU版本的opencv常用方法介绍
2020/07/24 Python
使用CSS3来制作消息提醒框
2015/07/12 HTML / CSS
奇怪的鱼:Weird Fish
2018/03/18 全球购物
西班牙宠物用品和食品网上商店:Tiendanimal
2019/06/06 全球购物
说出数据连接池的工作机制是什么?
2013/04/19 面试题
教师自我鉴定范文
2014/03/20 职场文书
和睦家庭事迹
2014/05/14 职场文书
房地产端午节活动方案
2014/08/24 职场文书
2014年财务部工作总结
2014/11/11 职场文书
订货会邀请函
2015/01/31 职场文书
喋血孤城观后感
2015/06/08 职场文书
开业庆典嘉宾致辞
2015/08/01 职场文书
深入理解以DEBUG方式线程的底层运行原理
2021/06/21 Java/Android