I am creating a jQuery plugin.
How do I get the real image width and height with Javascript in Safari?
The following works with Firefox 3, IE7 and Opera 9:
Recently I needed to find width and height for setting default size of .dialog representing graph. Solution I use was :
graph= $('<img/>', {"src":'mySRC', id:'graph-img'});
graph.bind('load', function (){
wid = graph.attr('width');
hei = graph.attr('height');
graph.dialog({ autoOpen: false, title: 'MyGraphTitle', height:hei, width:wid })
})
For me this works in FF3, Opera 10, IE 8,7,6
P.S. You may be find some more solutions looking inside some plugins like LightBox or ColorBox
I've done some workaround utility function, using imagesLoaded jquery plugin: https://github.com/desandro/imagesloaded
function waitForImageSize(src, func, ctx){
if(!ctx)ctx = window;
var img = new Image();
img.src = src;
$(img).imagesLoaded($.proxy(function(){
var w = this.img.innerWidth||this.img.naturalWidth;
var h = this.img.innerHeight||this.img.naturalHeight;
this.func.call(this.ctx, w, h, this.img);
},{img: img, func: func, ctx: ctx}));
},
You can use this by passing url, function and its context. Function is performed after image is loaded and return created image, its width and height.
waitForImageSize("image.png", function(w,h){alert(w+","+h)},this)
$(document).ready(function(){
var image = $("#fix_img");
var w = image.width();
var h = image.height();
var mr = 274/200;
var ir = w/h
if(ir > mr){
image.height(200);
image.width(200*ir);
} else{
image.width(274);
image.height(274/ir);
}
});
// This code helps to show image with 200*274 dimention
Webkit browsers set the height and width property after the image is loaded. Instead of using timeouts, I'd recommend using an image's onload event. Here's a quick example:
var img = $("img")[0]; // Get my img elem
var pic_real_width, pic_real_height;
$("<img/>") // Make in memory copy of image to avoid css issues
.attr("src", $(img).attr("src"))
.load(function() {
pic_real_width = this.width; // Note: $(this).width() will not
pic_real_height = this.height; // work for in memory images.
});
To avoid any of the effects CSS might have on the image's dimensions, the code above makes an in memory copy of the image. This is a very clever solution suggested by FDisk.
You can also use the naturalHeight
and naturalWidth
HTML5 attributes.
$("#myImg").one("load",function(){
//do something, like getting image width/height
}).each(function(){
if(this.complete) $(this).trigger("load");
});
From Chris' comment: http://api.jquery.com/load-event/
To add to Xavi's answer, Paul Irish's github David Desandro's gitgub offers a function called imagesLoaded() that works on the same principles, and gets around the problem of some browser's cached images not firing the .load() event (with clever original_src -> data_uri -> original_src switching).
It's is widely used and updated regularly, which contributes to it being the most robust solution to the problem, IMO.