jQuery $(document).ready()和JavaScript onload事件

Why we need a right time? 

  对元素的操作和事件的绑定需要等待一个合适的时机,可以看下面的例子:

<!DOCTYPE html>
<meta charset="utf-8">
<html> <head>
<title>1-1</title>
<script type="text/javascript">
document.getElementById("panel").onclick = function () {
alert("元素已经加载完毕 !");
}
/*执行错误*/
</script>
</head> <body>
<div id="panel">click me.</div>
</body> </html>

wrong case

  如果这样,还没有等待元素加载完就绑定事件,

  浏览器Console中会报错:
  TypeError: document.getElementById(...) is null
 
  更改一下时机,下面三个程序都是可以成功绑定事件的,点击元素之后会弹出相应的alert().
  第一种是把事件绑定放在body里,元素之后:
<!DOCTYPE html>
<meta charset="utf-8">
<html> <head>
<title>1-2</title>
</head> <body>
<div id="panel">click me.</div>
<script type="text/javascript">
document.getElementById("panel").onclick = function () {
alert("元素已经加载完毕 !");
}
/*正确执行*/
</script>
</body> </html>

right way 1: in body

  第二种是放在window.onload中进行事件绑定:
<!DOCTYPE html>
<meta charset="utf-8">
<html> <head>
<title>1-3</title>
<script type="text/javascript">
window.onload = function () {
document.getElementById("panel").onclick = function () {
alert("元素已经加载完毕 !");
}
}
</script>
</head> <body>
<div id="panel">click me.</div>
</body> </html>

right way 2: window.onload

  第三种是jQuery的ready()方法传入绑定事件的方法:
<!DOCTYPE html>
<meta charset="utf-8">
<html> <head>
<title>Panel</title>
<script src="jquery-1.11.2.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function () {
document.getElementById("panel").onclick = function () {
alert("元素已经加载完毕 !");
}
})
</script>
</head> <body>
<div id="panel">click me.</div>
</body> </html>

right way 3: ready()

jQuery $(document).ready()和window.onload

  根据ready()方法的API说明http://api.jquery.com/ready/
  这个方法接收一个function类型的参数ready(handler), 方法的作用是: Specify a function to execute when the DOM is fully loaded.
  即当DOM加载完毕的时候,执行这个指定的方法.
  因为只有document的状态ready之后,对page的操作才是安全的.
  $(document).ready()仅在DOM准备好的时候执行一次.
 
  与之相比,load事件会等到页面渲染完成执行,即等到所有的资源(比如图片)都完全加载完成的时候.
  $(window).load(function(){…})会等整个页面,不仅仅是DOM,还包括图像和iframes都准备好之后,再执行.
  而ready()是在DOM准备好之后就执行了,即DOM树建立完成的时候.所以通常ready()是一个更好的时机.
 
  如果DOM初始化完成之后再调用ready()方法,传入的新的handler将会立即执行.
 
  注意:ready()方法多次调用,传入的handler方法会串联执行(追加).
  而JavaScript中,window.onload是赋值一个方法,即后面的会覆盖掉前面的.
 
  看例子:
<!DOCTYPE html>
<meta charset="utf-8">
<html> <head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title></title>
<script src="jquery-1.11.2.js" type="text/javascript"></script>
<script type="text/javascript">
var startTime = new Date().getTime();
$(document).ready(function () {
var readyTime = new Date().getTime() - startTime;
$("<div>jQuery的ready() : " + readyTime + " ms</div>").appendTo("body");
})
$(document).ready(function () {
var readyTime2 = new Date().getTime() - startTime;
$("<div>jQuery的ready() 2 : " + readyTime2 + " ms</div>").appendTo("body");
})
window.onload = function () {
var windowOnLoadTime = new Date().getTime() - startTime;
$("<div>window.onload : " + windowOnLoadTime + " ms</div>").appendTo("body");
}
window.onload = function () {
var windowOnLoadTime2 = new Date().getTime() - startTime;
$("<div>window.onload 2 : " + windowOnLoadTime2 + " ms</div>").appendTo("body");
}
</script>
</head> <body>
<img src="http://www.google.com.hk/logos/2011/cezanne11-hp.jpg" style="width:200px;height:200px;"/>
</body> </html>
 
    在浏览器中打开显示如下:
  例子说明并验证了前面提到的两个问题:
  1.jQuery的ready()方法调用时机比window.onload提前.
  window.onload要等待页面中的资源(图像)加载完成,而ready()在DOM树建立好之后就调用了.
  2.ready()方法调用后,传入的方法是追加的形式,所以两个方法都调用了;
  而window.onload是赋值的形式,所以后面的方法覆盖了前面的方法.
 

$(document).ready()的三种简写

  $(document).ready()有三种方式来写,它们是等价的:
  $( document ).ready( handler )
  $().ready( handler ) (this is not recommended)
  $( handler )

  因为.ready()方法仅在当前document的jQuery对象上才可以调用,所以selector可以被省略.

 

window对象和document对象

  Window对象表示浏览器中打开的窗口: http://www.w3school.com.cn/jsref/dom_obj_window.asp
  Document对象表示载入浏览器的HTML文档: http://www.w3school.com.cn/jsref/dom_obj_document.asp
 

Event对象

  Event即事件,代表了各种状态:http://www.w3school.com.cn/jsref/dom_obj_event.asp
  事件句柄使我们可以在事件发生的时候附加一些操作和处理,比如按钮点击事件发生的时候,进行什么什么操作.
  上面的参考链接中含有一个属性列表,对应各种事件,可以利用这些属性定义事件的行为.
  本文关注的onload就是其中一个事件.
 

onload事件

  onload事件是在加载完成后立即发生.(注意其中的l是小写).
  支持该事件的标签是:
  <body>, <frame>, <frameset>, <iframe>, <img>, <link>, <script>
  支持该事件的JavaScript对象是:
  image, layer, window.
  注意这里并没有document.
 
onload使用解析
  最常用的就是window.onload, 会等到整个页面及各种资源都加载完成之后再执行后面赋值的function行为.
  另外,可以在标签中使用onload,比如:
<body onload="inlineBodyOnloadTimeCounter();">
  其中inlineBodyOnloadTimeCounter()是一个自定义的JavaScript function.
  注意jQuery ready()的API文档中有这么一段: 
The .ready() method is generally incompatible with the attribute. If load must be used, either do not use .ready() or use jQuery's .load() method to attach load event handlers to the window or to more specific items, like images.

  说明ready()方法和<body onload=“”>是不兼容的.

 
  看下面的例子:
<!DOCTYPE html>
<meta charset="utf-8">
<html> <head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title></title>
<script src="jquery-1.11.2.js" type="text/javascript"></script>
<script type="text/javascript">
var startTime = new Date().getTime();
$(document).ready(function () {
var readyTime = new Date().getTime() - startTime;
$("<div>jQuery的ready() : " + readyTime + " ms</div>").appendTo("body");
})
window.onload = function () {
var windowOnLoadTime = new Date().getTime() - startTime;
$("<div>window.onload : " + windowOnLoadTime + " ms</div>").appendTo("body");
} function inlineBodyOnloadTimeCounter() {
var bodyOnLoadTime = new Date().getTime() - startTime;
$("<div>body onload: " + bodyOnLoadTime + " ms</div>").appendTo("body");
}
</script>
</head> <body onload="inlineBodyOnloadTimeCounter();">
<img src="http://www.google.com.hk/logos/2011/cezanne11-hp.jpg" style="width:200px;height:200px;"/>
</body>
</html>
 
  在Chrome中:
 
  在FireFox中:
 
  说明Chrome中<body onload=“”>和window.onload是两个分开的事件;
  而FF中,<body onload=“”>会覆盖掉window.onload中的方法.
 
 
  再加上一个document.body.onload:
<!DOCTYPE html>
<meta charset="utf-8">
<html> <head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title></title>
<script src="jquery-1.11.2.js" type="text/javascript"></script>
<script type="text/javascript">
var startTime = new Date().getTime();
$(document).ready(function() {
var readyTime = new Date().getTime() - startTime;
$("<div>jQuery的ready() : " + readyTime + " ms</div>").appendTo("body");
})
window.onload = function() {
var windowOnLoadTime = new Date().getTime() - startTime;
$("<div>window.onload : " + windowOnLoadTime + " ms</div>").appendTo("body");
}
if (document.body) {
/*
document.body.onload = function() {
var documentBodyOnLoadTime = new Date().getTime() - startTime;
$("<div>document.body.onload() : " + documentBodyOnLoadTime + " ms</div>").appendTo("body");
}
*/
//This codes will not be executed.
} else {
console.log("=======document.body doesn't exist!=======");
} function inlineBodyOnloadTimeCounter() {
var bodyOnLoadTime = new Date().getTime() - startTime;
$("<div>body onload: " + bodyOnLoadTime + " ms</div>").appendTo("body");
}
</script>
</head> <body onload="inlineBodyOnloadTimeCounter();">
<img src="http://www.google.com.hk/logos/2011/cezanne11-hp.jpg" style="width:200px;height:200px;" />
<script type="text/javascript">
console.log("script in body!");
if (document.body) {
console.log("====document.body exist now!====");
document.body.onload = function() {
var documentBodyOnLoadTime = new Date().getTime() - startTime;
$("<div>document.body.onload: " + documentBodyOnLoadTime + " ms</div>").appendTo("body");
}
} else {
console.log("no document.body!");
}
</script> </body> </html>
 
  有下面几点发现:
  1.在执行<head>中的脚本时,document.body是null,只有当执行到<body>中的脚本段,document.body才不是null.
  这时候才能给其onload赋值.
  console中的log如下:
"=======document.body doesn't exist!======="
"script in body!"
"====document.body exist now!===="
  2.在Chrome中打开的时候:
  jQuery的ready() : 20 ms

  body onload: 207 ms
  document.body.onload: 208 ms
  前面一个例子显示了ready(),window.onload和body onload,说明此时document.body.onload覆盖了window.onload.
 
  3.在FireFox中打开显示:
  jQuery的ready() : 10 ms
  document.body.onload: 229 ms
  前面一个例子显示ready()和body onload,说明此时document.body.onload又覆盖了body onload. 
  另外单独测试了一下,的确document.body.onload会覆盖window.onload,代码略去.
  
 
结论:
在Chrome中:
  ready()
  window.onload==document.body.onload
  <body onload=“">
 
在FireFox中:
  ready()
  window.onload==<body onload=“”>==document.body.onload
 
  此分析的结果跟浏览器,甚至浏览器版本相关,本文写于2015.2.6
  Chrome Version: 40.0.2214.94
  FireFox Version: 35.0
 

参考资料

  jQuery API ready(): http://api.jquery.com/ready/
 
 

jQuery $(document).ready()和JavaScript onload事件的更多相关文章

  1. $(document).Ready()方法 VS OnLoad事件 VS $(window).load()方法

    $(document).Ready()方法 VS OnLoad事件 VS $(window).load()方法接触JQuery一般最先学到的是何时启动事件.在曾经很长一段时间里,在页面载入后引发的事件 ...

  2. jQuery $(document).ready()和window.onload

    jQuery $(document).ready()和window.onload 根据ready()方法的API说明http://api.jquery.com/ready/. 这个方法接收一个func ...

  3. 转载jquery $(document).ready() 与window.onload的区别

    jquery $(document).ready() 与window.onload的区别 投稿:mdxy-dxy 字体:[增加 减小] 类型:转载 时间:2009-12-28我要评论 Jquery中$ ...

  4. 转 $(document).ready()与window.onload的区别

    $(document).ready()和window.onload在表单上看都是页面加载时我们就去执行一个函数或动作,但是在具体的细节上$(document).ready()和window.onloa ...

  5. jQuery中的$(window).load()与$(document).ready()以及jquery $(document).ready() 与window.onload的区别

    大多数jQuery实例或教程都告诉我们绑定我们的jQuery代码到$(document).ready事件.虽然$(document).ready 事件在大多数情况下都OK,但是它的解析顺序是在文档准备 ...

  6. $(document).ready() 和 window.onload 方法比较

    说明 页面加载文档完毕后,浏览器会通过 Javascript 为 DOM 元素添加事件. Javascript 使用 window.onload 方法,而 jQuery 使用 $(document). ...

  7. 细说document.ready和window.onload

    原文 简书原文:https://www.jianshu.com/p/bbf28d61aa1f 大纲 1.对页面加载的认识 2.关于document.ready() 3.关于document.onloa ...

  8. jquery mobile在页面加载时添加加载中效果 document.ready 和window.onload执行顺序比较

    想要添加这个效果,先来弄明白页面的加载和事件执行顺序,看这个简单例子: <html xmlns="http://www.w3.org/1999/xhtml"> < ...

  9. $(document).ready() 与 window.onload 之间的区别

    1.执行时机 window.onload 是网页中所有的元素都加载到浏览器后才执行 $(document).ready() 是dom完全就续就可以调用 例如:如果给一副图片添加点击事件,window. ...

随机推荐

  1. 深入理解客户区尺寸client

    前面的话 关于元素尺寸,一般地,有偏移大小offset.客户区大小client和滚动大小scroll.前文已经介绍过偏移属性,后文将介绍scroll滚动大小,本文主要介绍客户区大小client 客户区 ...

  2. Android之TabActivity的使用

    TabActivity实现多页显示效果 由于手机屏幕有限,所以我们要尽量充分利用屏幕资源.在我们的应用程序中通常有多个Activity,而且会经常切换显示,这样我们就可以用TabActivity来显示 ...

  3. java笔试题

    下面有关JVM内存,说法错误的是? A.程序计数器是一个比较小的内存区域,用于指示当前线程所执行的字节码执行到了第几行,是线程隔离的 B.Java方法执行内存模型,用于存储局部变量,操作数栈,动态链接 ...

  4. 详解 ML2 Core Plugin(I) - 每天5分钟玩转 OpenStack(71)

    我们在 Neutron Server 小节学习到 Core Plugin,其功能是维护数据库中 network, subnet 和 port 的状态,并负责调用相应的 agent 在 network ...

  5. 窥探Swift编程之错误处理与异常抛出

    在Swift 2.0版本中,Swift语言对其错误处理进行了新的设计,当然了,重新设计后的结果使得该错误处理系统用起来更爽.今天博客的主题就是系统的搞一下Swift中的错误处理,以及看一下Swift中 ...

  6. hibernate笔记--通过SchemaExport生成数据库表

    方法比较简单,项目中只需要两个java类(一个实体类,如User,一个工具类),两个配置文件(hibernate必须的两个配置文件hibernate.cfg.xml,与User.hbm.xml),即可 ...

  7. 在Visual Studio 2012中使用VMSDK开发领域特定语言(二)

    本文为<在Visual Studio 2012中使用VMSDK开发领域特定语言>专题文章的第二部分,在这部分内容中,将以实际应用为例,介绍开发DSL的主要步骤,包括设计.定制.调试.发布以 ...

  8. DirectShow Filter的开发实践

    一.介绍 摄像头图像采集处理在业界有着多种成熟的方案.从老的DirectShow.Grabber技术,到新的Windows Media Foundation框架,网络上都有着丰富的参考资料.OpenC ...

  9. compilation与编译

    关于本配置节的内容不算多,但关于ASP.NET编译的内容还是有一点的,鄙人认为只是了解一下即可,主要影响到部署. 在 App_Code 文件夹中使用多种编程语言 因为 App_Code 文件夹中的源代 ...

  10. 如何汉化XAF应用

    这是一个入门级的问题,应网友请求,总结一下XAF汉化过程的几个关键点. 一.所有Dev的控件的汉化,Dev官方有汉化文件.点击下载15.2版本. 正版用户登陆至官网是有专门的下载界面的,并且可以参与汉 ...