document.ready还是不够快
我曾经在日志里介绍过jQuery的document.ready:
document.ready()和传统的方法<body onload=”load()”>相似,不同的是onload()的方法是在页面加载完成后才发生,这包括DOM元素和其他页面元素(例如图片)的加载,因此,使用document.ready()方法的执行速度比onload()的方法要快。
document.ready()可以说是jQuery的一大特色,它不仅比传统的Javascript函数onload()要快,而且加上jQuery强大的选择器可以在不用修改HTML代码情况下(例如:不用在HTML标签加入onClick()函数来调用其它自定义Javascript函数)对Web页面中的各种元素和事件进行控制、实现和Web客户交互的作用。
可是有时document.ready()并非你想像的那么快,我在最近的一个project里就碰到这个问题。例如一个页面含有多个相似的链接,每一个链接的HTML代码大致如下:
<a rel="popin" href="/cart/?popin=yes&act=add&sku=xxx"><img src="/images/new/buynow.gif" border="0" /></a>
当这些链接被点击后,相对应的物品(sku)就会被加入购物篮,为让客户点击链接后不用离开当前页面,我使用了jQuery的ajax方法,从后台调用添加购物篮函数,然后返回xml响应,最后把xml携带的信息通过HTML层(layer)传递给客户。大致的jQuery+ajax代码如下:
$(document).ready(function(){$("a[rel^='popin']").click(function(){$.ajax({url: $(this).attr('href'),type: 'GET',dataType: 'xml',error: function(){alert('Error loading XML document');},success: function(xml){$('#cart_sum1').html($(xml).find('cart').text());$('#buynow-result').html($(xml).find('pop').text());$('#buynow-inform').show('slow');$('#cart_sum2').html($(xml).find('cart').text());}});return false;});});
注意到我用了document.ready,试图在DOM ready的时候给这些链接(<a[rel^='popin'>)绑定点击事件控制。这在我的机子(windowxp+firefox3)里测试通过,但是在我老板的机子(redhat+firefox)上,有时会出现点击链接后跳出XML代码,原因很明显: 当她点击链接的时候,链接还没有被绑定事件控制,也就是说document.reday()还是不够快。
怎么解决?我有打算在链接代码里加入传统Javscript的onClick函数,这样当客户点击链接的时候,先调用onClick函数,然后在onClick函数里在调用ajax,应该就可以解决问题。今天想看看别人都是怎么解决这个问题,就用Google搜索了一下。找到这篇论坛问答,觉得说的挺有道理:
- Using window.onload waits until the whole page is loaded. (onload是在页面加载后起作用)
- Using document.ready waits until the whole DOM is ready (document.ready是在DOM 准备好后起作用)
- Having the script at the end of the body without document.ready, that doesn't wait. (把去掉document.ready的jQuery代码放在</body>前,无需等待)
准备明天到公司试试这种方法。其实把Javascript放在</body>前的说法以前也有看到过,Google的Analytics代码就建议放在</body>前。
Updated:(3/24/08)
经测试,第三种方法也不好用,主要问题是在页面没有完全加载完毕时,链接就已经被点击,这时</body>前的那一段jQuery代码还没有被加载,因此链接还没有被绑定ajax事件控制。
最终的解决办法是,把上面那段jQuery代码写出一个函数,反正header里,然后结合传统Javascript onClick函数,在链接被点击时直接调用header里函数。具体更改如下:
1. jQuery函数 (这段函数被放在header里)
function ajax_add(url_str){//把jquery代码写成一个函数$.ajax({url: url_str,type: 'GET',dataType: 'xml',//timeout: 5000,error: function(){alert('Error loading XML document');},success: function(xml){$('#cart_sum1').html($(xml).find('cart').text());$('#buynow-result').html($(xml).find('pop').text());$('#buynow-inform').show('slow');$('#cart_sum2').html($(xml).find('cart').text());}});}
2. 链接代码:
注意:链接直接加入<a onClick="add_ajax('/cart/?popin=yes&act=add&sku=xxx')" href="#"><img src="/images/new/buynow.gif" border="0" /></a>
onClick事件控制,而不在页面加载后绑定事件控制。这样就可以避免链接被点击时,事件还没有绑定的问题。 标签: Javascript, Jquery



3 条评论:
前几天在一本书上看到了 onload 和 .ready 的区别!!就是这个样子的,但具体的不太记得了!!
作者
xiaorsz, 时间
2009年3月24日 下午12:51
onload 不如document.ready快是肯定的,但是现在的问题是document.ready在有些情况下还是不够快的,就比如文中的例子。
另外,文中介绍的第三种方法(去掉document.ready,把
jquery代码放在body的最后面)经测试也是解决不了问题。具体的解决方法,请参考本文的更新。
作者
D Cai, 时间
2009年3月24日 下午5:14
好文章,把問題描述的很清楚,我今天正好遇到這問題,後來也是用onClick的方式解決!
作者
Joe's Blog 資訊.數位學習.生活, 时间
2009年10月20日 上午10:52
发表评论
指向此帖子的链接: