设为首页收藏本站

ZMX - IT技术交流论坛 - 无限Perfect,追求梦想 - itzmx.com

 找回密码
 注册论坛

QQ登录

只需一步,快速开始

新浪微博账号登陆

只需一步,快速开始

用百度帐号登录

只需两步,快速登录

搜索
查看: 1541|回复: 0

jQuery ready方法实现原理详解

[复制链接]

签到天数: 36 天

[LV.5]常住居民I

发表于 2016/11/4 15:22 | 显示全部楼层 |阅读模式 |Google Chrome 45.0.2454.101|Windows 7
天涯海角搜一下: 百度 谷歌 360 搜狗 有道 雅虎 必应 即刻
  先普及一下jquery.ready()和window.onload,window.onload事件是在页面所有的资源都加载完毕后触发的。 如果页面上有大图片等资源响应缓慢, 会导致window.onload事件迟迟无法触发。所以出现了DOM Ready事件。 此事件在DOM文档结构准备完毕后触发, 即在资源加载前触发。

  jQuery中的ready方法实现了当页面加载完成后才执行的效果,但他并不是window.onload或者doucment.onload的封装,而是使用 标准W3C浏览器DOM隐藏api和IE浏览器缺陷来完成的,首先,我们来看jQuery的代码

  ?

  1

  2

  3

  4

  5

  6

  7

  8

  9

  10

  11

  12

  13

  14

  DOMContentLoaded = function()

  {

  //取消事件监听,执行ready方法

  if ( document.addEventListener )

  {

  document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );

  jQuery.ready();

  }

  else if ( document.readyState === "complete" )

  {

  document.detachEvent( "onreadystatechange", DOMContentLoaded );

  jQuery.ready();

  }

  };

  ?

  1

  2

  3

  4

  5

  6

  7

  8

  9

  10

  11

  12

  13

  14

  15

  16

  17

  18

  19

  20

  21

  22

  23

  24

  25

  26

  27

  28

  29

  30

  31

  32

  33

  34

  35

  36

  37

  38

  39

  40

  41

  42

  43

  44

  45

  46

  47

  48

  49

  50

  51

  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 );

  };

  <br>

  ?

  1

  2

  3

  4

  5

  6

  7

  8

  9

  10

  11

  12

  13

  14

  15

  16

  17

  18

  19

  20

  21

  22

  23

  24

  25

  26

  27

  28

  29

  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 ) {www.9ask.cn/xiamen/

  jQuery( document )。trigger("ready")。off("ready");

  }

  }
欢迎光临IT技术交流论坛:http://bbs.itzmx.com/
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册论坛 新浪微博账号登陆用百度帐号登录

本版积分规则

手机版|Archiver|Mail me|网站地图|IT技术交流论坛 ( 闽ICP备13013206号-7 )

GMT+8, 2024/11/26 19:34 , Processed in 0.096532 second(s), 21 queries , MemCache On.

Powered by itzmx! X3.4

© 2011- sakura

快速回复 返回顶部 返回列表