jQuery回调图像加载(即使图像缓存)

我想做的是:

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

但是当图像从缓存中加载时,load事件不会触发。jQuery文档建议一个插件来修复这个问题,但是不管用

414572 次浏览

我是否可以建议您将其重新加载到非dom图像对象中?如果它被缓存,这将完全不花费时间,onload仍然会触发。如果它没有被缓存,它将在图像加载时触发onload,这应该与图像的DOM版本完成加载的时间相同。

Javascript:

$(document).ready(function() {
var tmpImg = new Image() ;
tmpImg.src = $('#img').attr('src') ;
tmpImg.onload = function() {
// Run onload code.
} ;
}) ;

更新(以处理多个图像和正确顺序的onload附件):

$(document).ready(function() {
var imageLoaded = function() {
// Run onload code.
}
$('#img').each(function() {
var tmpImg = new Image() ;
tmpImg.onload = imageLoaded ;
tmpImg.src = $(this).attr('src') ;
}) ;
}) ;

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

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

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

如果已经设置了src,则在绑定事件处理程序之前,事件就会在缓存的情况下触发。要修复这个问题,你可以循环检查并触发基于.complete的事件,如下所示:

$("img").one("load", function() {
// do stuff
}).each(function() {
if(this.complete) {
$(this).load(); // For jQuery < 3.0
// $(this).trigger('load'); // For jQuery >= 3.0
}
});

注意从.bind().one()的变化,因此事件处理程序不会运行两次。

对GUS示例的修改:

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


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

在onload之前和之后设置源。

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

$('img').asynchImageLoader({callback : function(){...}});

HTML应该是这样的

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

如果你想这样做,我可以给你一个小建议:

<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>

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

我有这个问题与IE的e.target.width将是未定义。加载事件会发生,但我无法在IE中获得图像的尺寸(chrome + FF工作)。

结果你需要寻找e.currentTarget.naturalWidth &e.currentTarget.naturalHeight

再说一次,IE有自己的(更复杂的)做事方式。

我自己也有这个问题,到处寻找一个解决方案,不涉及杀死我的缓存或下载插件。

我没有立即看到这个帖子,所以我发现了一些其他的东西,这是一个有趣的修复,(我认为)值得张贴在这里:

$('.image').load(function(){
// stuff
}).attr('src', 'new_src');

我实际上从这里的评论中得到了这个想法:http://www.witheringtree.com/2009/05/image-load-event-binding-with-ie-using-jquery/

我不知道为什么它能工作,但我已经在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

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

/**
* 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);
});
}
});
};

像这样使用它:

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:

.main_container{
position: relative;
width: 500px;
height: 300px;
background-color: #cccccc;
}


.center_horizontally{
position: absolute;
width: 100px;
height: 100px;
background-color: green;
left: 50%;
top: 0;
transform: translate(-50%,0);
}


.center_vertically{
position: absolute;
top: 50%;
left: 0;
width: 100px;
height: 100px;
background-color: blue;
transform: translate(0,-50%);
}


.center{
position: absolute;
top: 50%;
left: 50%;
width: 100px;
height: 100px;
background-color: red;
transform: translate(-50%,-50%);
}

HTML:

<div class="main_container">
<div class="center_horizontally"></div>
<div class="center_vertically"></div>
<div class="center"></div>
</div>
</div

< a href = " http://codepen。io / neoRiley /钢笔/ aZdRBm rel =“nofollow”> < / > Codepen例子

< a href = " http://codepen。io/neoRiley/pen/dXGgQe" rel="nofollow"> code depen LESS example . io/neoRiley/pen/dXGgQe" rel="nofollow"> code depen LESS example

解决方案我发现< A href="https://bugs.chromium.org/p/chromium/issues/detail?id=7731#c12" rel="noreferrer">https://bugs.chromium.org/p/chromium/issues/detail?id=7731#c12 (此代码直接取自注释)

var photo = document.getElementById('image_id');
var img = new Image();
img.addEventListener('load', myFunction, false);
img.src = 'http://newimgsource.jpg';
photo.src = img.src;