jQuery的图像加载callback(即使图像caching)

我想要做:

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

但是,从caching中加载图像时,加载事件不会触发。 jQuery的文档build议一个插件来解决这个问题,但它不起作用

如果src已经被设置,那么事件在被caching的情况下触发,甚至在事件处理程序被绑定之前。 为了解决这个问题,你可以循环检查并基于.complete触发事件,如下所示:

 $("img").one("load", function() { // do stuff }).each(function() { if(this.complete) $(this).load(); }); 

注意从.bind().one()的更改,所以事件处理程序不会运行两次。

我可以build议你重新加载到一个非DOM的图像对象? 如果它被caching,这将不会花费任何时间,onload仍然会被触发。 如果没有被caching,它会在图像加载时触发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') ; }) ; }) ; 

我简单的解决scheme,它不需要任何外部插件,对于一般情况下,应该是足够的:

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

或者作为select,如果你喜欢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); }); 

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

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

每次从caching中加载图像时都会触发。

我自己也遇到了这个问题,到处寻找解决scheme,不涉及杀死我的caching或下载插件。

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

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

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

我不知道为什么它的工作原理,但我已经testing了这个IE7和它现在的工作之前,它打破了。

希望它有帮助,

编辑

接受的答案实际上解释了原因:

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

您也可以使用此代码支持加载错误:

 $("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(); } }); 

对GUS例子的修改:

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

在onload之前和之后设置源。

通过使用jQuery与图像的src生成一个新的图像,并直接为其分配load方法,当jQuery完成生成新图像时,load方法被成功调用。 这在IE 8,9和10中适用于我

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

在定义img对象之后,只需在单独的行上重新添加src参数即可。 这将欺骗IE触发小伙子事件。 这是丑陋的,但它是迄今为止我find的最简单的解决方法。

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

我可以给你一点小费,如果你想这样做:

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

如果您在浏览器caching图片时这样做,总是显示img,但在实际图片下加载img并不成问题。

我有这个问题,IE浏览器的e.target.width将是未定义的。 加载事件会触发,但我无法得到在IE浏览器(铬+ FF工作)图像的尺寸。

原来你需要寻找e.currentTarget.naturalWidthe.currentTarget.naturalHeight

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

如果你想要一个纯粹的CSS解决scheme,这个技巧很好用 – 使用转换对象。 这也适用于caching或不caching的图像:

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 

Codepen示例

Codepen LESS示例

您可以使用JAIL插件来解决您的问题,该插件还允许您延迟加载图像(改进页面性能)并将callback作为parameter passing

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

HTML应该看起来像

 <img name="/globalhttp://img.dovov.comsample1.jpg" src="/globalhttp://img.dovov.comblank.gif" width="width" height="height" /> 

我find了一个解决schemehttps://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;