映像加载时的jQuery回调(即使在缓存映像时)

映像加载时的jQuery回调(即使在缓存映像时),jquery,image,jquery-events,jquery-load,Jquery,Image,Jquery Events,Jquery Load,我想做: $("img").bind('load', function() { // do stuff }); 但从缓存加载图像时,不会触发加载事件。建议修复此问题,但是我可以建议您将其重新加载到非DOM图像对象中吗?如果它被缓存,这将根本不需要时间,并且onload仍然会启动。如果它没有被缓存,它将在加载映像时触发onload,这应该与映像的DOM版本完成加载的时间相同 Javascript: $(document).ready(function() { var tmpImg =

我想做:

$("img").bind('load', function() {
  // do stuff
});

但从缓存加载图像时,不会触发加载事件。建议修复此问题,但是我可以建议您将其重新加载到非DOM图像对象中吗?如果它被缓存,这将根本不需要时间,并且onload仍然会启动。如果它没有被缓存,它将在加载映像时触发onload,这应该与映像的DOM版本完成加载的时间相同

Javascript:

$(document).ready(function() {
    var tmpImg = new Image() ;
    tmpImg.src = $('#img').attr('src') ;
    tmpImg.onload = function() {
        // Run onload code.
    } ;
}) ;
已更新(用于处理多个图像并使用正确排序的加载附件):


你真的必须用jQuery来做吗?您也可以将
onload
事件直接附加到图像上

<img src="/path/to/image.jpg" onload="doStuff(this);" />


无论是否从缓存加载映像,它都将在每次加载映像时触发。

如果已设置
src
,则在绑定事件处理程序之前,事件将在缓存的案例中触发。要解决此问题,可以循环检查并触发基于
的事件。完成
,如下所示:

$("img").one("load", function() {
  // do stuff
}).each(function() {
  if(this.complete) {
      $(this).load(); // For jQuery < 3.0 
      // $(this).trigger('load'); // For jQuery >= 3.0 
  }
});
<div style="position:relative;width:100px;height:100px">
     <img src="loading.jpg" style='position:absolute;width:100px;height:100px;z-index:0'/>
     <img onLoad="$(this).fadeIn('normal').siblings('img').fadeOut('normal')" src="picture.jpg" style="display:none;position:absolute;width:100px;height:100px;z-index:1"/>
</div>
onImgLoad('img', function(){
    // do stuff
});
$(“img”).one(“加载”,函数(){
//做事
}).each(函数({
如果(完成此项){
$(this).load();//对于jQuery<3.0
//$(this.trigger('load');//对于jQuery>=3.0
}
});

请注意从到的更改,以便事件处理程序不会运行两次。

对GUS示例的修改:

$(document).ready(function() {
    var tmpImg = new Image() ;
    tmpImg.onload = function() {
        // Run onload code.
    } ;

tmpImg.src = $('#img').attr('src');
})

在加载之前和之后设置源。

您可以使用插件解决问题,该插件还允许您延迟加载图像(提高页面性能)并将回调作为参数传递

$('img').asynchImageLoader({callback : function(){...}});
HTML应该如下所示

<img name="/global/images/sample1.jpg" src="/global/images/blank.gif" width="width" height="height" />

如果你想这样做,我可以给你一点提示:

$("img").one("load", function() {
  // do stuff
}).each(function() {
  if(this.complete) {
      $(this).load(); // For jQuery < 3.0 
      // $(this).trigger('load'); // For jQuery >= 3.0 
  }
});
<div style="position:relative;width:100px;height:100px">
     <img src="loading.jpg" style='position:absolute;width:100px;height:100px;z-index:0'/>
     <img onLoad="$(this).fadeIn('normal').siblings('img').fadeOut('normal')" src="picture.jpg" style="display:none;position:absolute;width:100px;height:100px;z-index:1"/>
</div>
onImgLoad('img', function(){
    // do stuff
});


如果在浏览器缓存图片时这样做,则始终显示img,但在真实图片下加载img是没有问题的。

我在IE中遇到了这个问题,其中e.target.width未定义。加载事件将触发,但我无法在IE中获取图像的尺寸(chrome+FF工作)

事实证明,您需要查找e.currentTarget.naturalWidthe.currentTarget.naturalHeight


又一次,IE以自己(更复杂)的方式做事情。

我自己也遇到了这个问题,到处寻找一个解决方案,而不是杀死我的缓存或下载插件

我没有立即看到这个帖子,所以我找到了一个有趣的补丁,值得在这里发布:

$('.image').load(function(){
    // stuff
}).attr('src', 'new_src');
实际上,我是从这里的评论中得到这个想法的:

我不知道它为什么会工作,但我已经在IE7上测试过了,在它开始工作之前它在哪里坏了

希望有帮助

编辑 公认的答案实际上解释了原因:

如果已经设置了src,那么在绑定事件处理程序之前,事件将在缓存中触发


通过使用jQuery生成带有图像src的新图像,并将load方法直接分配给该图像,当jQuery完成生成新图像时,将成功调用load方法。这在IE 8、9和10中对我有效

$('<img />', {
    "src": $("#img").attr("src")
}).load(function(){
    // Do something
});

$(“在定义img项目后,只需在另一行重新添加src参数。这将诱使IE触发lad事件。这很难看,但这是迄今为止我发现的最简单的解决方法

jQuery('<img/>', {
    src: url,
    id: 'whatever'
})
.load(function() {
})
.appendTo('#someelement');
$('#whatever').attr('src', url); // trigger .load on IE

jQuery(“我的简单解决方案,它不需要任何外部插件,对于常见情况应该足够了:

/**
 * Trigger a callback when the selected images are loaded:
 * @param {String} selector
 * @param {Function} callback
  */
var onImgLoad = function(selector, callback){
    $(selector).each(function(){
        if (this.complete || /*for IE 10-*/ $(this).height() > 0) {
            callback.apply(this);
        }
        else {
            $(this).on('load', function(){
                callback.apply(this);
            });
        }
    });
};
像这样使用它:

$("img").one("load", function() {
  // do stuff
}).each(function() {
  if(this.complete) {
      $(this).load(); // For jQuery < 3.0 
      // $(this).trigger('load'); // For jQuery >= 3.0 
  }
});
<div style="position:relative;width:100px;height:100px">
     <img src="loading.jpg" style='position:absolute;width:100px;height:100px;z-index:0'/>
     <img onLoad="$(this).fadeIn('normal').siblings('img').fadeOut('normal')" src="picture.jpg" style="display:none;position:absolute;width:100px;height:100px;z-index:1"/>
</div>
onImgLoad('img', function(){
    // do stuff
});
例如,要在加载时淡入图像,可以执行以下操作:

$('img').hide();
onImgLoad('img', function(){
    $(this).fadeIn(700);
});

或者,如果您更喜欢类似jquery插件的方法:

/**
 * Trigger a callback when 'this' image is loaded:
 * @param {Function} callback
 */
(function($){
    $.fn.imgLoad = function(callback) {
        return this.each(function() {
            if (callback) {
                if (this.complete || /*for IE 10-*/ $(this).height() > 0) {
                    callback.apply(this);
                }
                else {
                    $(this).on('load', function(){
                        callback.apply(this);
                    });
                }
            }
        });
    };
})(jQuery);
并以这种方式使用它:

$('img').imgLoad(function(){
    // do stuff
});
例如:

$('img').hide().imgLoad(function(){
    $(this).fadeIn(700);
});

您还可以在支持加载错误的情况下使用此代码:

$("img").on('load', function() {
  // do stuff on success
})
.on('error', function() {
  // do stuff on smth wrong (error 404, etc.)
})
.each(function() {
    if(this.complete) {
      $(this).load();
    } else if(this.error) {
      $(this).error();
    }
});

如果你想要一个纯CSS解决方案,这个技巧非常有效-使用transform对象。这也适用于缓存或不缓存的图像:

CSS:

HTML:


我找到了一个解决办法
(此代码直接取自注释)


在添加之前,您应该尝试附加
load
处理程序,这也不起作用,但对于一个图像,OPs代码适用于许多图像:)谢谢,我添加了一个更新版本,我希望能够解决这两个问题。
#img
是一个ID而不是元素选择器:)也
这个.src
有效,不需要在不需要jQuery的地方使用jQuery:),但在任何情况下创建另一个映像都似乎有些过分。它应该是$('img')。但解决方案是2k15中的gr8也是如此,对于多图像的情况,如果您想对
imageLoaded
中的每个图像操作DOM元素,那么使用
tmp.onload=imageLoaded.bind(this)
就像@Gus的答案一样,这对多个图像不起作用…并且在附加
onload
处理程序之前不需要设置
src
,一次之后就足够了。您的解决方案对我来说非常有效,但我想了解一下,在加载图像内容之后或之前,何时运行此代码“if(this.complete)”?因为正如我从这里可以理解的那样。你在所有$(“img”)上循环的每个图像内容都可能是空的,并且不会发生加载。嗯,我想我遗漏了一些东西,如果你能描述一下这件事,以便更好地理解它,那就太好了。谢谢。因为你的回答,事情变了。现在有一个小的工作插件。它们修复了所有问题。我将在“load”函数中添加一个
setTimeout(function(){//do stuff},0)
。。。0给了浏览器系统(DOM)一个额外的记号,以确保所有内容都得到正确更新。@Lode-这是一个巨大的插件,任何规模都不小!!由于JQuery 3方法
.load()
不会触发事件,并且有一个必需的参数,因此请使用
.trigger(“load”)
而不是因为您的问题发生了变化。这个坏掉的插件被转移到了一个gist,后来又转移到了一个带有一个小插件的repo。他们修复了所有的。上面提到的JQuery库对我来说工作得很好。谢谢谢谢你的插件,