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 相关文章推荐
15 个 JavaScript Web UI 库
May 19 Javascript
Javascript 中 null、NaN和undefined的区别总结
Apr 10 Javascript
Jquery为a标签的href赋值实现代码
May 03 Javascript
jquery删除提示框弹出是否删除对话框
Jan 07 Javascript
JS继承用法实例分析
Feb 05 Javascript
学习javascript面向对象 实例讲解面向对象选项卡
Jan 04 Javascript
Bootstrap栅格系统学习笔记
Nov 25 Javascript
jQuery实现联动下拉列表查询框
Jan 04 Javascript
Bootstrap下拉菜单更改为悬停(hover)触发的方法
May 24 Javascript
jQuery Validate插件ajax方式验证输入值的实例
Dec 21 jQuery
js构造函数创建对象是否加new问题
Jan 22 Javascript
使用Typescript开发微信小程序的步骤详解
Jan 12 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
图片存储与浏览一例(Linux+Apache+PHP+MySQL)
2006/10/09 PHP
一个PHP缓存类代码(附详细说明)
2011/06/09 PHP
PHP 下载文件时自动添加bom头的方法实例
2014/01/10 PHP
比Jquery的document.ready更快的方法
2010/04/28 Javascript
jquery增加时编辑jqGrid(实例代码)
2013/11/08 Javascript
js 一个关于图片onload加载的事
2013/11/10 Javascript
JavaScript中的值类型转换介绍
2014/12/31 Javascript
jQuery实现TAB选项卡切换特效简单演示
2016/03/04 Javascript
jQuery插件formValidator实现表单验证
2016/05/23 Javascript
vue组件Prop传递数据的实现示例
2017/08/17 Javascript
新手vue构建单页面应用实例代码
2017/09/18 Javascript
解决Jquery下拉框数据动态获取的问题
2018/01/25 jQuery
Vue2 轮播图slide组件实例代码
2018/05/31 Javascript
详解Vue微信授权登录前后端分离较为优雅的解决方案
2018/06/29 Javascript
基于Vue-cli快速搭建项目的完整步骤
2018/11/03 Javascript
微信小程序实现省市区三级地址选择
2020/06/21 Javascript
微信小程序扫描二维码获取信息实例详解
2019/05/07 Javascript
layui数据表格实现重载数据表格功能(搜索功能)
2019/07/27 Javascript
JavaScript设计模式--简单工厂模式定义与应用案例详解
2020/05/23 Javascript
vue在响应头response中获取自定义headers操作
2020/07/24 Javascript
Vue 请求传公共参数的操作
2020/07/31 Javascript
react-native 实现购物车滑动删除效果的示例代码
2021/01/15 Javascript
python不换行之end=与逗号的意思及用途
2017/11/21 Python
快速解决pyqt5窗体关闭后子线程不同时退出的问题
2019/06/19 Python
Python学习笔记之错误和异常及访问错误消息详解
2019/08/08 Python
html5各种页面切换效果和模态对话框用法总结
2014/12/15 HTML / CSS
亚历山大·王官网:Alexander Wang
2017/06/23 全球购物
意大利在线药房:shop-farmacia.it
2019/03/12 全球购物
Miller Harris官网:英国小众香水品牌
2020/09/24 全球购物
Linux内核产生并发的原因
2016/11/08 面试题
军人违纪检讨书
2014/02/04 职场文书
经典毕业生求职信
2014/07/12 职场文书
关于学习的决心书
2015/02/05 职场文书
2015年超市收银员工作总结
2015/04/25 职场文书
2015年化妆品销售工作总结
2015/05/11 职场文书
Python 循环读取数据内存不足的解决方案
2021/05/25 Python