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.naturalWidth & e.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;