图片的load 事件在加载时被触发(doh!),而且至关重要的是,如果您在加载之前连接您的处理程序,您的处理程序将无法获取叫。浏览器将并行加载资源,因此您无法确定(即使在 jQuery 的 ready 事件中表明页面的 DOM 已准备好)当您的代码运行时图像尚未加载。
您可以使用图像对象的complete 属性来知道它是否已经被加载,所以:
var firstPhoto = $("#photos img:first");
if (firstPhoto[0].complete) {
// Already loaded, call the handler directly
handler();
}
else {
// Not loaded yet, register the handler
firstPhoto.load(handler);
}
function handler() {
alert("Image loaded!");
}
如果所讨论的浏览器确实实现了多线程加载,其中图像加载可能发生在与 Javascript 线程不同的线程上,甚至可能存在竞争条件。
当然,如果您的选择器将匹配多张图片,您需要处理它;您的选择器看起来应该只匹配一个,所以...
编辑这个版本允许多张图片,我认为它可以处理任何非 Javascript 的竞争条件(当然,目前有 em> 没有 Javascript 竞争条件;Javascript 本身在浏览器中是单线程的 [除非你使用新的 web workers 东西]):
function onImageReady(selector, handler) {
var list;
// If given a string, use it as a selector; else use what we're given
list = typeof selector === 'string' ? $(selector) : selector;
// Hook up each image individually
list.each(function(index, element) {
if (element.complete) {
// Already loaded, fire the handler (asynchronously)
setTimeout(function() {
fireHandler.call(element);
}, 0); // Won't really be 0, but close
}
else {
// Hook up the handler
$(element).bind('load', fireHandler);
}
});
function fireHandler(event) {
// Unbind us if we were bound
$(this).unbind('load', fireHandler);
// Call the handler
handler.call(this);
}
}
// Usage:
onImageReady("#photos img:first");
几点说明:
- 回调没有得到
event对象;如果你愿意,你可以修改它,但当然,在图像已经加载的情况下不会有任何事件,所以它的实用性有限。
- 您可以使用
one 代替bind 和unbind,但我喜欢这种清晰度,而且我很偏执。 :-)