I ran into a problem on Chrome and Safari using jQuery to do some calculations using the widths of a strip of images.
When using my calculations in:
$(document).ready(function() {
/* some calculations with $("img").width() */
});
everything works just fine in IE6+ and Firefox, but it does not in Chrome and Safari: $(img).width() is 0 whether the image is already cached or not.
Using:
$(window).load(function() {
/* some calculations with $("img").width() */
});
it works in all the above mentioned browsers but the problem is it only starts when all images are completely loaded.
Is the webkit behaviour the expected behaviour or is there some webkit / jQuery bug causing the image properties not to be a part of the DOM?
If it is a problem with webkit / jQuery: Is there a way around it that will allow my script to execute earlier than in the above mentioned solution?
By the way, I am not using any inline properties for the image dimensions.
Try specifying the sizes in your img tags:
<img src="myimg.jpg" alt="" width="300" height="200" />
A quick google search about this:
http://www.websiteoptimization.com/speed/tweak/size/
What I'm deducing is since the images aren't loaded, webkit will simply return 0 as an 'unknown' size until the image has been loaded. Specifically stating the size might solve this.
I feel this is more of hack-ish way, but it seems to work (from what I've tested):
function callback(){
var el = $(this);
// if this element was processed or width is 0 (for webkit), then skip
if(el.data('loaded') || el.width() === 0)
return;
el.data('loaded', 1); // marked this element as "processed"
// do whatever you want to do with el.width()
console.log(el.width());
}
$(function(){
// Non-webkit-based browsers will call callback() here
// otherwise, after each image loads, the callback will execute
// (for webkit browsers), when the size will be correct.
$('img').load(callback).each(callback);
})
Webkit-browsers will still be slightly slower than other browsers because it's after each image finishes loading, but it's faster than waiting for all the images to load.
I'm not a fan of offloading tasks to the client that should be handled on the server.
The real solution is to calculate the image-size when it is added to your database, then generating the <img> tag correctly with width and height attributes before sending it to the client.
Any overhead incurred in the initial calculation (and pulling the values from the database afterwards) would be minuscule compared to the process of uploading it to the database in the first place -- not to mention each subsequent retrieval of it later.
The result is a semantically meaningful HTML-tag that works with jQuery in all browsers you care about, so why avoid it?
I found this way of specifying image sizes when dynamically loading images using .load(), I use an image loading function with a callback
loadImage: function(src, callback){
$("<img alt="" />").attr("src", src).load(callback);
}
and then I can use the img-element (which reports the correct size) to set the img-attributes inside the callback
$(this).attr({
id: img,
width: this.width,
height: this.height
});
and now I can get the proper widht and height using, for example,
var contentWidth = $("#img").attr("width");