I know there is a lot of these on Stackoverflow but I haven\'t found one that works for me in a recent version of jquery (1.10.2).
I did try:
$(\".lazy
I usually do this:
var image = new Image();
image.onload = function () {
console.info("Image loaded !");
//do something...
}
image.onerror = function () {
console.error("Cannot load image");
//do something else...
}
image.src = "/images/blah/foo.jpg";
Remember that the loading is asynchronous so you have to continue the script inside the onload and onerror events.
There's also a useful .complete
property of an image object, you can use it if you have already set the .src
of your <img>
before attaching to it any event listeners:
var img=document.getElementById('myimg');
var func=function(){
// do your code here
// `this` refers to the img object
};
if(img.complete){
func.call(img);
}
else{
img.onload=func;
}
Reference: http://www.w3schools.com/jsref/prop_img_complete.asp
What I need to do is fire an image resize function once the images are loaded.
Are you sure that you need the image to be loaded? Waiting for an image to load before resizing it can cause a large jump in the page layout, especially if the images have large file sizes, such as animated GIFs.
Usually, for an image resize, you only need to know the intrinsic dimensions of the image. While there is no event to tell you this, it's easy enough to poll the images for the data. Something like this could be particularly effective:
<img src="..." data-resizeme="123" />
(function() {
var images, l, i, tmp;
if( document.querySelectorAll) {
images = [].slice.call(document.querySelectorAll("img[data-resizeme]"),0);
}
else {
tmp = document.getElementsByTagName("img");
images = [];
// browser compatibility is fun!
for( i=tmp.length-1; i>=0; i--) {
if( tmp[i].getAttribute("data-resizeme")) images.unshift(tmp[i]);
}
}
for( i=images.length-1; i>=0; i--) {
images[i].onload = resizeImage;
images[i].onerror = cancelImageResize;
}
var timer = setInterval(function() {
for( i=images.length-1; i>=0; i--) {
if( images[i].width) {
resizeImage.call(images[i]);
images[i].onload = null;
cancelImageResize.call(images[i]);
}
}
if( images.length == 0) clearInterval(timer);
},100); // adjust granularity as needed - lower number is more responsive.
function cancelImageResize() {
var i;
for( i=images.length-1; i>=0; i--) {
if( images[i] == this) {
images.splice(i,1);
break;
}
}
}
function resizeImage() {
console.log("Image "+this.src+" is "+this.width+"x"+this.height);
}
})();
Hope this helps!
In the case of waiting of loading multiple images:
var images = $("#div-with-images img");
var unloaded = images.length;
images.on('load', function(){
-- unloaded;
if (!unloaded) {
// here all images loaded, do your stuff
}
});
I would give the images that require this constraint a class like mustLoad
where:
<img class="mustLoad" src="..." alt="" />
and then create a generic image load handler function, such as:
$('img.mustLoad').on('load',function(){
/* Fire your image resize code here */
});
Edit:
In response to your comments about deprecating .load()
above, .load()
was deprecated, in favor of .on('load')
to reduce ambiguity between the onLoad
event and Ajax loading.