jquery $(document).ready() 与window.onload的区别
Jquery中$(document).ready()的作用类似于传统JavaScript中的window.onload方法,不过与window.onload方法还是有区别的。
1.执行时间
window.onload必须等到页面内包括图片的所有元素加载完毕后才能执行。
$(document).ready()是DOM结构绘制完毕后就执行,不必等到加载完毕。
2.编写个数不同
window.onload不能同时编写多个,如果有多个window.onload方法,只会执行一个
$(document).ready()可以同时编写多个,并且都可以得到执行
3.简化写法
window.onload没有简化写法
$(document).ready(function(){})可以简写成$(function(){});
在我以前的开发中,一般用到javascript,我都是采用jquery的模式,也就是大多数时候,第一行写的是:
$(document).ready(function(){ ... });
这个时候,不一定要等所有的js和图片加载完毕,就可以执行一些方法。
不过有些时候,必须要等所有的元素都加载完毕,才可以执行一些方法的时候,比如说,部分图片或者什么其他方面还没有加载好,这个时候,点击某些按钮,会导致出现意外的情况,这个时候,就需要用到:
$(window).load(function() { $("#btn-upload").click(function(){ //比如说: uploadPhotos(); }); });
用$(window).load(function(){...})而不用body.onload()的几个理由如下:
首先它们都是在页面所有元素(包括html标签以及引用到得所有图片、Flash等媒体)加载完毕后执行的,这是它们的共同点。
不用body.onload()理由1:
如果我们想同时加载多个函数,我们必须这样写
<body onload="fn1(),fn2()"></body>看起来既不美观、也不方便后期项目维护,如果用$(window).load()我们可以这样加载多个函数,代码如下:
$(window).load(function() { alert("hello,我是jQuery!"); }); $(window).load(function() { alert("hello,我也是jQuery"); });
这样写它会从上往下执行这两个函数,并且看起来漂亮多了。
不用body.onload()理由2:
用body.onload()不能够做到js和html的完全分离,这是一个很严重的问题(会影响项目的后期维护)。
另外用$(window).load(function(){...})和body.onload()都存在同样一个问题:它们都需要等到页面的所有内容加载完毕才执行。
但是如果当网速比较慢的时候,加载一个页面往往需要较长的时间(几秒到十几秒不等,甚至更长...),所以我们经常会遇到页面还没有完全加载完毕而用户已经在操作页面了这种情况,这样页面表现出来的效果就跟我们预期的效果不一样了,所以在这种情况下推荐使用$(document).ready(function(){}),或简写为$(function(){}),因为他会在页面的dom元素加载完毕后就执行,而无需等到图片或其他媒体下载完毕。
但是有时候确实我们有需要等到页面的所有东西都加载完后再执行我们想执行的函数,所以是该使用$(window).load(function(){...})还是该使用$(function(){})往往需要结合具体需要而作不同的选择。
最后附上一段在所有DOM元素加载之前执行的jQuery代码:
<script type="text/javascript"> (function() { alert("DOM还没加载哦!"); })(jQuery) </script>
window.onload不能同时编写多个,若存在多个,则只会执行最后一个:
window.onload = function(){ alert(“text1”); }; window.onload = function(){ alert(“text2”); };
上面的代码只会执行第二个,仅有一个弹出框:text2。
但是,如果存在多个$(document).ready,那么会依次执行:
$(document).ready(function(){ alert(“Hello World”); }); $(document).ready(function(){ alert(“Hello again”); });
上面这段代码,会依次弹出:Hello World、Hello again。
说明:
由于在 $(document).ready() 方法内注册的事件,只要 DOM 就绪就会被执行,因此可能此时元素的关联文件未下载完。例如与图片有关的 html 下载完毕,并且已经解析为 DOM 树了,但很有可能图片还没有加载完毕,所以例如图片的高度和宽度这样的属性此时不一定有效。
要解决这个问题,可以使用 Jquery 中另一个关于页面加载的方法 ---load() 方法:
Load() 方法会在元素的 onload 事件中绑定一个处理函数。
如果处理函数绑定给 window 对象,则会在所有内容 ( 包括窗口、框架、对象和图像等 ) 加载完毕后触发;
如果处理函数绑定在元素上,则会在元素的内容加载完毕后触发。
最近在改一个嵌入在frame中的页面的时候,使用了jquery做效果,而页面本身也绑定了onload事件。改完后,Firefox下测试正常流畅,IE下就要等个十几秒jquery的效果才出现,黄花菜都凉了。
起初以为是和本身onload加载的方法冲突。网上普遍的说法是$(document).ready()是在页面DOM解析完成后执行,而onload事件是在所有资源都准备完成之后才执行,也就是说$(document).ready()是要在onload之前执行的,尤其当页面图片较大较多的时候,这个时间差可能更大。可是我这页面分明是图片都显示出来十几秒了,还不见jquery的效果出来。
删了onload加载的方法试试,结果还是一样,看来没有必要把原本的onload事件绑定也改用$(document).ready()来写。那是什么原因使得Firefox正常而IE就能呢?接着调试,发现IE下原来绑定的onload方法竟然先于$(document).ready()的内容执行,而Firefox则是先执行$(document).ready()的内容,再执行原来的onload方法。这个和网上的说法似乎不完全一致啊,呵呵,有点意思、、、、、
翻翻jquery的源码看看$(document).ready()是如何实现的吧:
if ( jQuery.browser.msie && window == top ) (function(){ if (jQuery.isReady) return; try { document.documentElement.doScroll("left"); } catch( error ) { setTimeout( arguments.callee, 0 ); return; } // and execute any waiting functions jQuery.ready(); })(); jQuery.event.add( window, "load", jQuery.ready );
结果很明了了,IE只有在页面不是嵌入frame中的情况下才和Firefox等一样,先执行$(document).ready()的内容,再执行原来的onload方法。
对于嵌入frame中的页面,也只是绑定在load事件上执行,所以自然是在原来的onload绑定的方法执行之后才轮到。而这个页面中正好在测试环境下有一个访问不到的资源,那十几秒的延迟正是它放大出的时间差。
以上就是本文的全部内容,了解更多jQuery的语法,大家可以查看:《jQuery 1.10.3 在线手册》。
参考文章地址:http://www.jb51.net/article/21628.htm