I want to create an alert box after an image is loaded, but if the image is saved in the browser cache, the .onload event will not be fired.
How do I trigger an alert when an image has been loaded regardless of whether the image has been cached or not?
var img = new Image();
img.src = "img.jpg";
img.onload = function () {
alert("image is loaded");
}
As you're generating the image dynamically, set the onload property before the src.
var img = new Image();
img.onload = function () {
alert("image is loaded");
}
img.src = "img.jpg";
Fiddle - tested on latest Firefox and Chrome releases.
You can also use the answer in this post, which I adapted for a single dynamically generated image:
var img = new Image();
// 'load' event
$(img).on('load', function() {
alert("image is loaded");
});
img.src = "img.jpg";
Fiddle
If the src is already set then the event is firing in the cached case before you even get the event handler bound. So, you should trigger the event based off .complete also.
code sample:
$("img").one("load", function() {
//do stuff
}).each(function() {
if(this.complete || /*for IE 10-*/ $(this).height() > 0)
$(this).load();
});
There are two possible solutions for these kind of situations:
Use the solution suggested on this post
Add a unique suffix to the image src to force browser downloading it again, like this:
var img = new Image();
img.src = "img.jpg?_="+(new Date().getTime());
img.onload = function () {
alert("image is loaded");
}
In this code every time adding current timestamp to the end of the image URL you make it unique and browser will download the image again
I have met the same issue today. After trying various method, I realize that just put the code of sizing inside $(window).load(function() {}) instead of document.ready would solve part of issue (if you are not ajaxing the page).
I found that you can just do this in Chrome:
$('.onload-fadein').each(function (k, v) {
v.onload = function () {
$(this).animate({opacity: 1}, 2000);
};
v.src = v.src;
});
Setting the .src to itself will trigger the onload event.
Related
I try to place multiple images in my HTML, and manipulate them when they are all loaded.
But onload event is not firing in IE9 sometimes.
I set some console debug message, and found that if the readyState of image is loading when I register onload event, onload event will not fire.
Code snippet is as follows:
var loaded = function () {
// increate counter to make sure all images are loaded or not
};
var thumbnails = $('img');
thumbnails.each(function () {
console.log('this.readyState:'+this.readyState)
if (this.complete) {
loaded();
} else {
this.onload = loaded;
}
});
P.S. I don't want to use window.onload method, because my script may be a plugin, it will be insert someone's page.
try re-assigning the image source (src) to trigger the event, like:
var thumbnails = $('img');
thumbnails.each(function () {
var img = $(this);
console.log('this.readyState:'+this.readyState)
if (this.complete) {
loaded();
} else {
this.onload = loaded;
}
img.attr('src', img.attr('src'));
});
The following code doesn't seem to work in IE (using 9) - Test 1 fires but test 2 does not. Is there a different way of doing this for IE?
<script>
$(document).ready(function () {
overlay = $("#overlay");
img = $("#myimg");
alert('test 1');
img.load(function () {
alert('test 2');
var myPercent = 50;
var myHeight = $("#myimg").height() / 100 * myPercent;
overlay.height(myHeight);
overlay.width($("#myimg").width());
$(".percent").css('margin-top', $("#myimg").height()/2 - $(".percent").height()/2);
$(".percent").text(myPercent + "%");
});
});
</script>
EDIT: Fixed it by using $(window).load(function() { instead of document ready and removing the function
From the jQuery API of .load()
Caveats of the load event when used with images
A common challenge developers attempt to solve using the .load()
shortcut is to execute a function when an image (or collection of
images) have completely loaded. There are several known caveats with
this that should be noted. These are:
It doesn't work consistently nor reliably cross-browser
It doesn't fire correctly in WebKit if the image src is set to the
same src as before
It doesn't correctly bubble up the DOM tree Can cease to fire for
images that already live in the browser's cache
Make use of $(window).load():
$(window).load(function() {
alert('test 2');
var myPercent = 50;
var myHeight = $("#myimg").height() / 100 * myPercent;
overlay.height(myHeight);
overlay.width($("#myimg").width());
$(".percent").css('margin-top', $("#myimg").height()/2 - $(".percent").height()/2);
$(".percent").text(myPercent + "%");
});
Technically you should be able to add onload parameter on img tag which calls js function that does the same thing. I haven't tested this but it's worth a shot.
...
<script>
function resizeImg ($img) {
// code
}
</script>
...
<img onload="resizeImg($(this));" src="foo.png" />
You might as well use jQuery then.
...
<script>
$("#fooImg").load(function () {
// code
});
</script>
...
<img id="fooImg" src="foo.png" />
If you don't mind using a plugin, Paul Irish made a simple plugin to handle image loading, seeing as .load() does not handle images. The plugin was moved and turned into a project which can be found on GitHub.
$.fn.imagesLoaded = function (callback) {
var elems = this.filter('img'),
len = elems.length,
// data uri bypasses webkit log warning (thx doug jones (cjboco))
blank = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==";
elems.bind('load', function () {
// check image src to prevent firing twice (thx doug jones (cjboco))
if (--len <= 0 && this.src !== blank) {
callback.call(elems, this);
}
}).each(function () {
// cached images don't fire load sometimes, so we reset src.
if (this.complete || this.complete === undefined) {
var src = this.src;
// webkit hack from http://groups.google.com/group/jquery-dev/browse_thread/thread/eee6ab7b2da50e1f
this.src = blank;
this.src = src;
}
});
};
You can see it in action at this fiddle.
http://jsfiddle.net/denniswaltermartinez/c4DMH/
img.load() as an event is not supported by IE. Actually it is not necessary, that $(document).ready() function has already ensure img and other elements loaded. Just remove it.
To make sure a document is ready before doing stuff, i do the following :
(function() {
var interval = window.setInterval(function() {
if("complete" === document.readyState) {
window.clearInterval(interval);
// Some stuff
}
}, 10);
})();
If somewhere in my code i create an image from JavaScript like this :
var image = new Image();
image.onload = function() {
// Some other stuff
};
image.src = 'some_url';
Will the check I perform on document.readyState also wait for "image" to be loaded, or will it just wait for the images present in the HTML code, and only those, to be loaded ?
Thanks in advance.
You don't need your setInterval.
From the MDN :
The load event fires at the end of the document loading process. At
this point, all of the objects in the document are in the DOM, and all
the images and sub-frames have finished loading.
You can simply do this for the statically included images :
window.onload = function() {
// Some stuff
};
As this doesn't take into account the images you create later, you may do this :
window.onload = function() {
var image = new Image();
image.onload = function(){
// Some stuff
};
image.src = 'some_url';
};
In jquery document.ready() function is call when entire html page is ready or we can say bind (in technical terms).
You should try with increasing Interval time. or include image load callback for performing the stuff.
Using the following script to add an event listener, basically it says "Hide the #curtain div (whole page) until .bgImage is downloaded, then wait 1500ms and fade everything in"
My question is this - sometimes due to server lag or glitchy triggering of .bind("load") the page is not fading in. How can I add some kind of timeOut to the effect so that it triggers after X miliseconds if the .bind("load) event is not triggered?
$(document).ready(function(){
// #curtain DIV begins hidden then fades in after .bgImage (curtain) is loaded - prevents "ribbon" loading effect in Chrome
$('#curtain').hide();
$(".bgImage").bind("load", function () {$('#curtain').delay(1500).fadeIn(); });
});
$(".bgImage").bind("load", function () {
setTimeout(function() {
$('#curtain').delay(1500).fadeIn();
}, 500);
});
if you want to add a delay to the fadeIn animation this will help. cheers
What you could do is this:
var url = $('.bgImage').attr('src');
var img = new Image();
img.onload = function() {
$('#curtain').delay(1500).fadeIn();
};
img.src = url;
In my experience, as long as you set up the "onload" property of an "Image" object before you set the "src", the handler will always run.
edit — if you wanted to be sure that the thing would eventually fade in, then you could do something like this:
var allDone = false;
var url = $('.bgImage').attr('src');
var img = new Image();
img.onload = function() {
if (!allDone) {
$('#curtain').delay(1500).fadeIn();
allDone = true;
}
};
setTimeout(img.onload, 5000); // show the hidden stuff after 5 seconds, image or no image
img.src = url;
You can use something like this:
var timeout;
$(".bgImage").bind("load", function(){
clearTimeout(timeout);
// do something here
});
timeout = setTimeout(function(){
$(".bgImage").unbind("load");
// do something else instead
}, 10000);
and maybe also handle errors:
$(".bgImage").bind("error", function(){
// do something else here as well
});
UPDATE: I added code to cancel your timeout when the load does happen. Those two functions has to be able to cancel out each other.
Try adding this to your css:
#curtain {
display:none;
}
and using this in your document read():
$(.bgImage).load(function() {
$('#curtain').fadeIn(3000);
});
I'm currently working on a page that loads several images sequentially using setTimeout and onLoad. Basically when an image finishes loading, onLoad is triggered, which starts another image loading via a setTimeout call. Unfortunately, if an image load is interrupted for some reason, such as a subsequent ajax call, onload is never called and any images left to be loaded are not loaded. Is there any way in javascript to detect this situation? I've attempted to hook into onError and onAbort (on the image tag) and neither of these seem to be called.
queuePhotos: function(options)
{
this.init();
this.photo_urls = options.photo_urls;
this.photo_size = options.size
this.max_width = options['max_width'];
this.max_height = options['max_height'];
this.containers = options['containers'];
yd = YAHOO.util.Dom;
photo_tags = yd.getElementsByClassName('image_stub', 'div');
for( i in photo_tags )
{
//create new image
photo = new Image();
this.queue.push( { tag: photo_tags[i], photo: photo } );
}
setTimeout(photoLoader.prepareNextPhoto, 1);
},
prepareNextPhoto: function()
{
photo_tag_and_image = photoLoader.queue.shift();
if(photo_tag_and_image)
{
YAHOO.util.Event.addListener(photo_tag_and_image.photo, "load", photoLoader.appendPhoto, photo_tag_and_image, photoLoader);
photo_tag_and_image.photo.src = photoLoader.photo_urls[photo_tag_and_image.tag.id];
}
},
An AJAX call shouldn't cancel the loading of images. There could be something else going on here...
I don't think that you can readily detect the load failure of an image. You could fire off a timer with a certain timeout threshold to deem an image as failed if your timeout timer expires before you get the load event from the image.
You can call onload and onerror
myImage.onload = function(){ alert("loaded"); };
myImage.onerror = function(){ alert("whoops"); };
Eric