I want to do:
$("img").bind('load', function() {
// do stuff
});
But the load event doesn't fire when the image is loaded from cache. The jQuery docs suggest a plugin to fix this, but it doesn't work
I want to do:
$("img").bind('load', function() {
// do stuff
});
But the load event doesn't fire when the image is loaded from cache. The jQuery docs suggest a plugin to fix this, but it doesn't work
If the src
is already set, then the event is firing in the cached case, before you even get the event handler bound. To fix this, you can loop through checking and triggering the event based off .complete
, like 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
}
});
Note the change from .bind()
to .one()
so the event handler doesn't run twice.
one
and complete
in Prototype (the library) ? –
Jabin setTimeout(function(){//do stuff},0)
within the 'load' function ... the 0 gives the browser system (DOM) one extra tick to ensure that everything is properly updated. –
Cyrenaica onerror
event. –
Aberdare one
instead of on
? using one
will not show the final dimension of the image –
Crystalcrystalline .one()
because you want it to fire once and only once. –
Panther 26 KB
it was significantly reduced –
Ketchan .bind
is deprecated, use .on
instead –
Paris .load()
does not trigger event and has 1 required argument, use .trigger("load")
instead –
Sickroom Can I suggest that you reload it into a non-DOM image object? If it's cached, this will take no time at all, and the onload will still fire. If it isn't cached, it will fire the onload when the image is loaded, which should be the same time as the DOM version of the image finishes loading.
Javascript:
$(document).ready(function() {
var tmpImg = new Image() ;
tmpImg.src = $('#img').attr('src') ;
tmpImg.onload = function() {
// Run onload code.
} ;
}) ;
Updated (to handle multiple images and with correctly ordered onload attachment):
$(document).ready(function() {
var imageLoaded = function() {
// Run onload code.
}
$('#img').each(function() {
var tmpImg = new Image() ;
tmpImg.onload = imageLoaded ;
tmpImg.src = $(this).attr('src') ;
}) ;
}) ;
load
handler before it's added, also this won't work but for one image, the OPs code works for many :) –
Panther #img
is an ID not an element selector :) Also this.src
works, no need to use jQuery where it isn't needed :) But creating another image seems like overkill in either case IMO. –
Panther imageLoaded
, then use tmp.onload = imageLoaded.bind(this)
–
Homage My simple solution, it doesn't need any external plugin and for common cases should be enough:
/**
* 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);
});
}
});
};
use it like this:
onImgLoad('img', function(){
// do stuff
});
for example, to fade in your images on load you can do:
$('img').hide();
onImgLoad('img', function(){
$(this).fadeIn(700);
});
Or as alternative, if you prefer a jquery plugin-like approach:
/**
* 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);
and use it in this way:
$('img').imgLoad(function(){
// do stuff
});
for example:
$('img').hide().imgLoad(function(){
$(this).fadeIn(700);
});
width
, max-height
and leave height:auto
, often it's necessary to set both width and height only if you need to stretch the image; for a more robust solution I would use a plugin like ImagesLoaded –
Doyen selector
in $()
- i.e., $(selector).each(...)
- is redundant, given that you already have called the function with a jQuery object - onImgLoad($('img'),...)
? –
Centaur Do you really have to do it with jQuery? You can attach the onload
event directly to your image as well;
<img src="/path/to/image.jpg" onload="doStuff(this);" />
It will fire every time the image has loaded, from cache or not.
onload
handler fire when the image is loaded a second time from cache? –
Blackbeard You can also use this code with support for loading error:
$("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();
}
});
load
handler first and then call it later in the each
function. –
Trickery I just had this problem myself, searched everywhere for a solution that didn't involve killing my cache or downloading a plugin.
I didn't see this thread immediately so I found something else instead which is an interesting fix and (I think) worthy of posting here:
$('.image').load(function(){
// stuff
}).attr('src', 'new_src');
I actually got this idea from the comments here: http://www.witheringtree.com/2009/05/image-load-event-binding-with-ie-using-jquery/
I have no idea why it works but I have tested this on IE7 and where it broke before it now works.
Hope it helps,
The accepted answer actually explains why:
If the src is already set then the event is firing in the cache cased before you get the event handler bound.
$image.load(function(){ something(); }).attr('src', $image.attr('src'));
to reset the original source. –
Eucaine By using jQuery to generate a new image with the image's src, and assigning the load method directly to that, the load method is successfully called when jQuery finishes generating the new image. This is working for me in IE 8, 9 and 10
$('<img />', {
"src": $("#img").attr("src")
}).load(function(){
// Do something
});
A solution I found https://bugs.chromium.org/p/chromium/issues/detail?id=7731#c12 (This code taken directly from the comment)
var photo = document.getElementById('image_id');
var img = new Image();
img.addEventListener('load', myFunction, false);
img.src = 'http://newimgsource.jpg';
photo.src = img.src;
A modification to GUS's example:
$(document).ready(function() {
var tmpImg = new Image() ;
tmpImg.onload = function() {
// Run onload code.
} ;
tmpImg.src = $('#img').attr('src');
})
Set the source before and after the onload.
src
before the attaching the onload
handler, once afterwards will suffice. –
Panther Just re-add the src argument on a separate line after the img oject is defined. This will trick IE into triggering the lad-event. It is ugly, but it is the simplest workaround I've found so far.
jQuery('<img/>', {
src: url,
id: 'whatever'
})
.load(function() {
})
.appendTo('#someelement');
$('#whatever').attr('src', url); // trigger .load on IE
I can give you a little tip if you want do like this:
<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>
If you do that when the browser caches pictures, it's no problem always img shown but loading img under real picture.
I had this problem with IE where the e.target.width would be undefined. The load event would fire but I couldn't get the dimensions of the image in IE (chrome + FF worked).
Turns out you need to look for e.currentTarget.naturalWidth & e.currentTarget.naturalHeight.
Once again, IE does things it's own (more complicated) way.
You can solve your problem using JAIL plugin that also allows you to lazy load images (improving the page performance) and passing the callback as parameter
$('img').asynchImageLoader({callback : function(){...}});
The HTML should look like
<img name="/global/images/sample1.jpg" src="/global/images/blank.gif" width="width" height="height" />
If you want a pure CSS solution, this trick works very well - use the transform object. This also works with images when they're cached or not:
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
© 2022 - 2024 — McMap. All rights reserved.