我正在尝试测试图像的加载时间,因此我可以更改不透明度并淡入其中,我想对所有使用.hphoto类的图像执行此操作。
这就是我尝试使用JQuery的方式:
function handle_photoloads() {
$(".hphoto").each(function (i,obj) {
console.log("Yo");
if ($(obj).complete) {
console.log("1");
$(obj).css('opacity','1');
} else {
console.log("incomplete");
$(obj).on('load',function () {
console.log("2");
$(obj).css('opacity','1');
});
}
});
}
$(document).ready(function() {
handle_photoloads();
});
我得到的输出是"哟"并且"不完整",并且我得到了每个输出中的一个.hphoto对象的数量,所以有些工作正常。为什么没有按预期触发负载处理程序?
答案 0 :(得分:3)
这一行是个问题:
if ($(obj).complete) {
您正在寻找jQuery对象上的complete
属性,而不是它包装的DOM元素。由于obj
指的是DOM元素,最简单的是:
if (obj.complete) { // Where `obj` refers to the DOM element
否则,请使用prop
,但在包装您知道的元素时,通常不会使用它:
if ($(obj).prop("complete")) { // Where `obj` refers to the DOM element
但是,请注意检查complete
标志然后添加处理程序会有 小 错过事件的机会。浏览器中的JavaScript只有一个UI线程,但浏览器不是单线程的。这是一个完全有效的事件序列:
JavaScript解释器评估$(obj).prop("complete")
并返回值false
。
浏览器的图像加载代码在另一个线程上运行,看到它已经完成加载该图像并检查是否有为load
事件注册的事件处理程序;没有看到任何内容,它不会为UI线程下次能够处理挂起的调用队列时添加任何处理程序回调。
JavaScript解释器在图像上挂钩load
事件。
赔率非常低,但可能会发生。
如果您对此感到担心,请首先挂钩处理程序 ,然后检查complete
,如果已设置,则调用您的处理程序并取消注册。与上述相反,您可能会得到两个调用而不是一个(因为事件发生在您挂钩处理程序之后但在检查complete
之前),但“有时两个”是比“有时为零”更好。 : - )
jQuery的巧妙命名one
函数在此上下文中非常有用:
function handle_photoloads() {
$(".hphoto").each(function (i,obj) {
var photo = $(obj); // Or = $(this), which would be more common
console.log("Yo");
photo.one("load", function() { // Note `one`, not `on`
photo.css('opacity','1');
});
if (photo.prop("complete")) {
photo.trigger("load");
}
});
}
one
在第一次调用时删除处理程序。所以我们只得到一次回调,无论时间如何。
(在上面,代替if (photo.prop("complete"))
,您可以if (photo[0].complete)
)