通过append()添加的Jquery图像会触发两次onload事件

6

导致我头痛的代码相当简单:

$(function(){ 
$("#test").append('<img onload="alert(\'hi\')" src="Image.jpg"/>');
})

我脑海中有上述代码,并且在正文中有一个ID为“test”的div。现在我的问题是,当图像加载时页面会产生两个警报,但我期望它只产生一个,因为“onload”应该只触发一次-当我手动添加图像而没有任何javascript时它的方式就是这样的。请参见我在http://jsfiddle.net/9985N/上制作的示例。
非常感谢您的任何帮助或解释...

使用.html(...)方法可以解决它,但我不知道为什么会发生这种情况。 - Teneff
可能有点离题,但是你不应该在图片上附加load - Jashwant
1
@Jashwant:你能解释一下为什么吗?因为我在这里没有看到W3C的人提到过这个问题:http://www.w3schools.com/jsref/event_img_onload.asp - Erric
先看看这个w3fools,然后再看看jQuery load - Jashwant
w3shools可能不提供良好的学习材料,但它对于元素参考非常有用。关于在jquery api网站上提到的注意事项-似乎是合理的,但这并不意味着我们永远不应该使用它(就我所理解的)。我在这里需要的唯一功能是跨浏览器兼容性,大多数现代浏览器都可以正常工作(例如:如果图像已缓存,则不希望调用函数...)。 - Erric
2个回答

6

更新(因为有些人不相信我,哈哈)

.append 方法首先创建节点,然后将其移动到适当的位置。请先添加元素,然后再按照以下方式添加其属性:

$(function() {
    $("#test").append(
        $("<img />").attr({
            src: "http://upload.wikimedia.org/wikipedia/commons/thumb/1/1a/Bachalpseeflowers.jpg/300px-Bachalpseeflowers.jpg",
            onload: "alert(\'hi\')"
        })
    );
});

我的回答并没有“回避”问题,它非常直接地回答了问题。如果您以未压缩的格式打开jQuery.js文件,您可以清楚地看到.append在文档中创建了node,这是onload事件首次调用的时间,然后shifts将其移动到位置,这是再次调用的时间。也许“shift”这个词不太合适,请原谅我,因为词汇不是我的强项。但是,如果您跟随代码,您会看到它的创建和移动,但是如果再次使用append来移动它,则不会说相同的话,因为节点已经创建,它只是从一个元素移动到另一个元素,而不需要重新启动onload。正如我所说的,不确定最佳术语,但是在jQuery.js上很容易跟随。

不相信我?刚在MSIE9、FF12和GoogleChrome20中测试了以下fiddle,没有问题。

jsFiddle

只是提醒一下,这并不是一个可怕的做法,但我总是看到人们用jQuery写整行HTML,这有点违背了它的目的。它是一个具有许多目的书籍的库。有时候,完整的HTML可能看起来更容易,但它可能不会更快,因为它没有遵循为您完成的所有出色布局工作。这个想法是“少写,多做”,包括HTML。毕竟,如果你要写整行HTML,为什么要使用jQuery呢?你不如直接在PHP中写!:P只是一个想法。


2
你的回答没有解决问题。实际上,即使不将对象附加到任何地方,只需将其包装在 $('<img...') 中,警报也会显示两次。请查看此链接 - Teneff
1
如果append是唯一的元素,为什么会移动它? - Jashwant
1
@tenneff:非常好的观点-不幸的是,这更增加了混乱-这是一个jQuery的错误吗? - Erric
1
顺便问一下,移动图像不会再次触发“onload”事件吧? - Erric
1
哇,更新真的澄清了很多东西,但是你能解释一下当我们像Teneff说的那样写$('<img...')会发生什么吗? - Erric

0

或者这样:

var img = $('<img src="http://upload.wikimedia.org/wikipedia/commons/thumb/1/1a/Bachalpseeflowers.jpg/300px-Bachalpseeflowers.jpg"/>').on('load', function(){
    $('#test').append(img);
    alert('loaded');  
});

与问题略有不同 - 您的代码在图像加载时附加,对吗?(我在谈论相反的情况) - Erric

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接