jquery事件的ready()方法使用详解


Posted in Javascript onNovember 11, 2015

页面初始化中,用的较多的就是$(document).ready(function(){//代码}); 或 $(window).load(function(){//代码});

他们的区别就是,ready是在DOM的结构加载完后就触发,load是在页面内包括DOM结构,css,js,图片等都加载完成后再触发,显然ready更适合作为页面初始化使用。但有时候也不尽然。需要进一步查看其内部机制。

那么ready的内部是如何判断DOM的结构加载完的?并且不同的浏览器的判断是如何的?

答案就在jquery代码内,假设jquery的版本是jquery-1.11.3.js。

ready的关键代码(3507~3566行),关键代码用红色标出:

jQuery.ready.promise = function( obj ) {
  if ( !readyList ) {

    readyList = jQuery.Deferred();

    // Catch cases where $(document).ready() is called after the browser event has already occurred.
    // we once tried to use readyState "interactive" here, but it caused issues like the one
    // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15
    if ( document.readyState === "complete" ) {
      // Handle it asynchronously to allow scripts the opportunity to delay ready
      setTimeout( jQuery.ready );

    // Standards-based browsers support DOMContentLoaded
    } else if ( document.addEventListener ) {
      // Use the handy event callback
      document.addEventListener( "DOMContentLoaded", completed, false );

      // A fallback to window.onload, that will always work
      window.addEventListener( "load", completed, false );

    // If IE event model is used
    } else {
      // Ensure firing before onload, maybe late but safe also for iframes
      document.attachEvent( "onreadystatechange", completed );

      // A fallback to window.onload, that will always work
      window.attachEvent( "onload", completed );

      // If IE and not a frame
      // continually check to see if the document is ready
      var top = false;

      try {
        top = window.frameElement == null && document.documentElement;
      } catch(e) {}

      if ( top && top.doScroll ) {
        (function doScrollCheck() {
          if ( !jQuery.isReady ) {

            try {
              // Use the trick by Diego Perini
              // http://javascript.nwbox.com/IEContentLoaded/
              top.doScroll("left");
            } catch(e) {
              return setTimeout( doScrollCheck, 50 );
            }

            // detach all dom ready events
            detach();

            // and execute any waiting functions
            jQuery.ready();
          }
        })();
      }
    }
  }
  return readyList.promise( obj );
};

上面的代码在触发ready时可以分成两部分

1.标准浏览器下的触发

当浏览器是基于标准浏览器时,会在加载完DOM结构后触发“DOMContentLoaded”事件,jquery内部就用此事件作为ready的触发源。

document.addEventListener( "DOMContentLoaded", completed, false );

2.IE浏览器下的触发

当浏览器是IE浏览器时,因为IE浏览器(蛋疼并强大着)不支持“DOMContentLoaded”事件,所以只能另谋它法,

(function doScrollCheck() {
          if ( !jQuery.isReady ) {

            try {
              // Use the trick by Diego Perini
              // http://javascript.nwbox.com/IEContentLoaded/
              top.doScroll("left");
            } catch(e) {
              return setTimeout( doScrollCheck, 50 );
            }

            // detach all dom ready events
            detach();

            // and execute any waiting functions
            jQuery.ready();
          }
        })();

IE下的做法 就是上面代码的红字处,用“document.documentElement.doScroll("left")”的方法去滚动页面,如果没加载完就等个50毫秒后继续滚,直到滚的动后就触发ready。

但是,如果页面中有frame的场合,会使用window.onload事件作为ready的触发源。

所以在IE下,页面中有frame时,ready也是等到页面内的所有内容加载完成后再触发。

jQuery中ready与load事件的区别

大家在工作中用jQuery的时候一定会在使用之前这样:

//document ready
$(document).ready(function(){
  ...code...
})
//document ready 简写
$(function(){
  ...code...
})

有些时候也会这么写:

//document load
$(document).load(function(){
  ...code...
})

一个是ready一个是load,这两个到底有什么区别呢?今天我们来聊一聊。
ready与load谁先执行:

大家在面试的过程中,经常会被问到一个问题:ready与load那一个先执行,那一个后执行?答案是ready先执行,load后执行。
DOM文档加载的步骤:

要想理解为什么ready先执行,load后执行就要先聊一下DOM文档加载的步骤:

(1) 解析HTML结构。
(2) 加载外部脚本和样式表文件。
(3) 解析并执行脚本代码。
(4) 构造HTML DOM模型。//ready
(5) 加载图片等外部文件。
(6) 页面加载完毕。//load

从上面的描述中大家应该已经理解了吧,ready在第(4)步完成之后就执行了。但是load要在第(6)步完成之后才执行。

ready事件:

ready事件在DOM结构绘制完成之后就绘执行。这样能确保就算有大量的媒体文件没加载出来,JS代码一样可以执行。

load事件:

load事件必须等到网页中所有内容全部加载完毕之后才被执行。如果一个网页中有大量的图片的话,则就会出现这种情况:网页文档已经呈现出来,但由于网页数据还没有完全加载完毕,导致load事件不能够即时被触发。

总结:

相信大家已经了解了ready与load的区别,其实如果页面中要是没有图片之类的媒体文件的话ready与load是差不多的,但是页面中有文件就不一样了,所以还是推荐大家在工作中用ready。

Javascript 相关文章推荐
兼容Mozilla必须知道的知识。
Jan 09 Javascript
Prototype 工具函数 学习
Jul 23 Javascript
JavaScript Accessor实现说明
Dec 06 Javascript
js制作的鼠标悬浮时产生的下拉框效果
Oct 27 Javascript
js判断字符是否是汉字的两种方法小结
Jan 03 Javascript
javascript实现的多个层切换效果通用函数实例
Jul 06 Javascript
js+css绘制颜色动态变化的圈中圈效果
Jan 27 Javascript
jQuery实现CheckBox全选、全不选功能
Jan 11 Javascript
vue.js过滤器+ajax实现事件监听及后台php数据交互实例
May 22 Javascript
vscode下的vue文件格式化问题
Nov 28 Javascript
基于JS实现简单滑块拼图游戏
Oct 12 Javascript
微信小程序wx.getUserInfo授权获取用户信息(头像、昵称)的实现
Aug 19 Javascript
浅谈使用MVC模式进行JavaScript程序开发
Nov 10 #Javascript
每天一篇javascript学习小结(基础知识)
Nov 10 #Javascript
jQuery+CSS3实现3D立方体旋转效果
Nov 10 #Javascript
JavaScript中利用各种循环进行遍历的方式总结
Nov 10 #Javascript
简单学习JavaScript中的for语句循环结构
Nov 10 #Javascript
js密码强度校验
Nov 10 #Javascript
详解javascript函数的参数
Nov 10 #Javascript
You might like
PHP安全配置
2006/12/06 PHP
dedecms防止FCK乱格式化你的代码的修改方法
2007/03/17 PHP
php建立Ftp连接的方法
2015/03/07 PHP
WordPress的文章自动添加关键词及关键词的SEO优化
2016/03/01 PHP
简单谈谈PHP中的Reload操作
2016/12/12 PHP
浅析PHP 中move_uploaded_file 上传中文文件名失败
2019/04/17 PHP
JavaScript asp.net 获取当前超链接中的文本
2009/04/14 Javascript
JavaScript 操作键盘的Enter事件(键盘任何事件),兼容多浏览器
2010/10/11 Javascript
js根据日期判断星座的示例代码
2014/01/23 Javascript
使用jquery.qrcode生成彩色二维码实例
2014/08/08 Javascript
JavaScript中的console.group()函数详细介绍
2014/12/29 Javascript
javascript面向对象之定义成员方法实例分析
2015/01/13 Javascript
jQuery左右滚动支持图片放大缩略图图片轮播代码分享
2015/08/26 Javascript
1秒50万字!js实现关键词匹配
2016/08/01 Javascript
JavaScript中最常见的三个面试题解析
2017/03/04 Javascript
Js判断H5上下滑动方向及滑动到顶部和底部判断的示例代码
2017/11/15 Javascript
详解webpack中的hash、chunkhash、contenthash区别
2018/01/05 Javascript
vue.js的vue-cli脚手架中使用百度地图API的实例
2019/01/21 Javascript
JavaScript数据结构与算法之二叉树实现查找最小值、最大值、给定值算法示例
2019/03/01 Javascript
Vue 刷新当前路由的实现代码
2019/09/26 Javascript
vue学习笔记之slot插槽基本用法实例分析
2020/02/01 Javascript
Javascript如何递归遍历本地文件夹
2020/08/06 Javascript
[01:12:35]Spirit vs Navi Supermajor小组赛 A组败者组第一轮 BO3 第二场 6.2
2018/06/03 DOTA
python实现的阳历转阴历(农历)算法
2014/04/25 Python
在Python下利用OpenCV来旋转图像的教程
2015/04/16 Python
Python合并两个字典的常用方法与效率比较
2015/06/17 Python
Python处理PDF及生成多层PDF实例代码
2017/04/24 Python
python3.x实现发送邮件功能
2018/05/22 Python
Django实现登录随机验证码的示例代码
2018/06/20 Python
对pandas中Series的map函数详解
2018/07/25 Python
ActiveMQ:使用Python访问ActiveMQ的方法
2019/01/30 Python
python实现淘宝购物系统
2019/10/25 Python
python中字典增加和删除使用方法
2020/09/30 Python
大学生入党自荐书
2015/03/05 职场文书
《我的长生果》教学反思
2016/02/20 职场文书
2019年大学毕业生个人自我鉴定范文大全
2019/03/21 职场文书