I have the following code snippet which is called on the success of the image uploading procedure.
success(data){
$avatar.attr('src', "/images/common/loading.gif");
$avatar.attr('src', data.url);
}
Here $avatar is the container for an image tag. The idea is to load this image with loading.gif until data.url is loaded successfully. Here data.url may contain a large size image which takes long time to load.
The problem is loading.gif is never loaded to the image container until I use setTimeOut as:
success(data){
$avatar.attr('src', "/images/common/loading.gif");
setTimeOut(function(){
$avatar.attr('src', data.url);
},100);
}
Can anyone suggest me some different approach rather than to use setTimeOut?
Showing uploaded image is more important than showing loader image But if you are doing it your way, go with the onload-event.
Also listen onerror event if loader image fails, or else avatar image will never get loaded!
success(data) {
var loader = new Image();
var loadMainImage = function() {
var mainImage = new Image();
mainImage.onload = function() { //avatar is loaded!
$avatar.attr('src', this.src);
}
mainImage.src = data.url;
}
loader.onload = function() { //loader is loaded!
$avatar.attr('src', this.src);
loadMainImage();
};
loader.onerror = mainImage; //loader is failed!
loader.src = "/images/common/loading.gif";
}
I think you can use beforeSend to handle async promises
Related
I'm looking to dynamically load in an image:
<img data-src="test01">
And then use jQuery to take the data-src and then load in the image associated with that name, PLUS the extension. If THAT extension fails, then move onto the next extension, so on and so on until we get to the bottom when I just load in a default image. But I don't know how to check if there's an error AFTER I've set the image's attr once. Here's the loop I have so far, and I'm getting ".error not a function"
$("img").each(function(){
var newSource = $(this).data('src').toString();
$(this).attr('src', 'images/'+newSource+'.gif').error(function(){
$(this).attr('src', 'images/'+newSource+'.jpg').error(function(){
$(this).attr('src', 'images/'+newSource+'.png').error(function(){
$(this).attr('src', 'images/default.jpg');
});
});
});
});
The reason I'm doing this is because we have a database that holds the title of the image only, yet, over the years, different people have uploaded different image formats to the site, and we want to be able to load all of them on the page, sans extension, and then loop through each extension until we find a file that exists, and if not, default to a pre-set hard coded image URL
One alternative would be to do a HEAD request for the urls. A benefit of a HEAD request is that it just tries to get headers for the endpoint, without trying to return data, so it can be super fast. In your case, it could be a quick check to see if an image url is valid or not.
function changeTheSrcIfTheUrlIsValid ( element, url ) {
return $.ajax({
url: url,
type: 'HEAD',
success: function(){
//got a success response, set the src
element.src = url;
}
});
}
$("img").each(function(){
var img = this;
var newSource = img.getAttribute('src');
//check for a gif
changeTheSrcIfTheUrlIsValid( img, 'images/'+ newSource +'.gif' )
.then(null, function(){
//error handler, try jpg next
changeTheSrcIfTheUrlIsValid( img, 'images/'+ newSource +'.jpg' )
.then(null, function(){
//error handler, try png next
changeTheSrcIfTheUrlIsValid( img, 'images/'+ newSource +'.png' )
.then(null, function(){
//error handler, use default
img.src = 'images/default.jpg';
});
});
});
});
Can use a Promise and a new Image() each time. The promise gets resolved or rejected in the onload or onerror of the new Image.
Then there is a chain of catch() to try various extensions and finally set a default noImageUrl if all else fail
Something like:
function setImageSrc(src, ext, el){
return new Promise(resolve, reject){
var url = 'images/'+src+ ext;
var img = new Image()
img.src = url
img.onerror = reject;
img.onload = function(){
el.src = url; // set src of current element in dom
resolve(url)
}
}
}
$("img").each(function(){
var newSource = $(this).data('src').toString();
var self = this
setImageSrc(newSource, '.jpg', self)
.catch(setImageSrc(newSource, '.png', self))
.catch(setImageSrc(newSource, '.gif', self))
.catch(function(){
self.src = 'noImageUrl';
});
});
is it possible to check the status codes of images using jQuery/JS?
For example,
img1 = "http://upload.wikimedia.org/wikipedia/commons/thumb/2/26/YellowLabradorLooking_new.jpg/260px-YellowLabradorLooking_new.jpg";
if(statusCheck(img1) == 404){
/do something
}elseif(statusCheck(img1) == 403){
//do something else
}elseif(statusCheck(img1) == 304){
//do something else
}
Thanks
You can construct an Image object, which isn't affected by cross-origin restrictions:
var image = new Image();
image.src = "http://upload.wikimedia.org/wikipedia/commons/thumb/2/26/YellowLabradorLooking_new.jpg/260px-YellowLabradorLooking_new.jpg"
image.onload = function() {
alert('Image has loaded');
};
image.onerror = function() {
alert('Image did not load');
};
Image loading is asynchronous, so making a function that returns the error code won't be a good idea.
Demo: http://jsfiddle.net/Blender/apyL7/
Also, there doesn't seem to be a way to get the response code, so you're limited to knowing only whether the image loaded or not.
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.
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.
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