我正在创建一个jQuery插件。

我如何得到真实的图像宽度和高度与Javascript在Safari?

Firefox 3、IE7和Opera 9的操作如下:

var pic = $("img")

// need to remove these in of case img-element has set width and height
pic.removeAttr("width"); 
pic.removeAttr("height");

var pic_real_width = pic.width();
var pic_real_height = pic.height();

但在Safari和谷歌等Webkit浏览器中,Chrome的值为0。


当前回答

这对缓存的和动态加载的图像都有效。

function LoadImage(imgSrc, callback){
  var image = new Image();
  image.src = imgSrc;
  if (image.complete) {
    callback(image);
    image.onload=function(){};
  } else {
    image.onload = function() {
      callback(image);
      // clear onLoad, IE behaves erratically with animated gifs otherwise
      image.onload=function(){};
    }
    image.onerror = function() {
        alert("Could not load image.");
    }
  }
}

使用此脚本:

function AlertImageSize(image) {
  alert("Image size: " + image.width + "x" + image.height);
}
LoadImage("http://example.org/image.png", AlertImageSize);

演示:http://jsfiddle.net/9543z/2/

其他回答

我检查了Dio的答案,它对我来说很有用。

$('#image').fadeIn(10,function () {var tmpW = $(this).width(); var tmpH = $(this).height(); });

确保你调用了所有的函数。在fadeIn()的召回函数中处理图像大小。

谢谢你。

如前所述,如果图像在缓存中,Xavi回答将不起作用。这个问题响应webkit没有对缓存的图像触发加载事件,所以如果在img标签中没有显式设置宽度/高度attrs,唯一可靠的获取图像的方法是等待窗口。加载要触发的事件。

窗外。加载事件总是会触发,所以在没有任何技巧的情况下,访问img的宽度/高度是安全的。

$(window).load(function(){

   //these all work

   $('img#someId').css('width');
   $('img#someId').width();
   $('img#someId').get(0).style.width;
   $('img#someId').get(0).width; 

});

如果需要获取可能被缓存的动态加载图像的大小(以前加载过),可以使用Xavi方法加上查询字符串来触发缓存刷新。缺点是它将导致对服务器的另一个请求,请求已经缓存并且应该已经可用的img。愚蠢的Webkit。

var pic_real_width   = 0,
    img_src_no_cache = $('img#someId').attr('src') + '?cache=' + Date.now();

$('<img/>').attr('src', img_src_no_cache).load(function(){

   pic_real_width = this.width;

});

ps:如果你在img中有一个QueryString。SRC,您将不得不解析它并添加额外的参数来清除缓存。

My situation is probably a little different. I am dynamically changing the src of an image via javascript and needed to ensure that the new image is sized proportionally to fit a fixed container (in a photo gallery). I initially just removed the width and height attributes of the image after it is loaded (via the image's load event) and reset these after calculating the preferred dimensions. However, that does not work in Safari and possibly IE (I have not tested it in IE thoroughly, but the image doesn't even show, so...).

Safari保留了前一张图片的尺寸所以尺寸总是在后面一张图片上。我认为这和缓存有关。因此,最简单的解决方案是克隆图像并将其添加到DOM中(重要的是将其添加到DOM中以获得with和height)。给图像一个可见值为hidden(不要使用display none,因为它不起作用)。获得尺寸后,删除克隆。

下面是我使用jQuery的代码:

// Hack for Safari and others
// clone the image and add it to the DOM
// to get the actual width and height
// of the newly loaded image

var cloned, 
    o_width, 
    o_height, 
    src = 'my_image.jpg', 
    img = [some existing image object];

$(img)
.load(function()
{
    $(this).removeAttr('height').removeAttr('width');
    cloned = $(this).clone().css({visibility:'hidden'});
    $('body').append(cloned);
    o_width = cloned.get(0).width; // I prefer to use native javascript for this
    o_height = cloned.get(0).height; // I prefer to use native javascript for this
    cloned.remove();
    $(this).attr({width:o_width, height:o_height});
})
.attr(src:src);

这个解决方案在任何情况下都有效。

正如Luke Smith所说,图像加载是一团糟。它在所有浏览器上都不可靠。这个事实给了我极大的痛苦。缓存的图像在某些浏览器中根本不会触发事件,所以那些说“图像加载比setTimeout更好”的人是错误的。

卢克·史密斯的解决方案在这里。

关于如何在jQuery 1.4中处理这些混乱的问题,有一个有趣的讨论。

我发现这是相当可靠的设置宽度为0,然后等待“完成”属性为真,宽度属性来大于零。您还应该注意错误。

关于从WebKit缓存加载图像时onload事件不会触发的问题,在已接受的回答中有很多讨论。

在我的例子中,onload触发了缓存图像,但高度和宽度仍然为0。一个简单的setTimeout解决了我的问题:

$("img").one("load", function(){
    var img = this;
    setTimeout(function(){
        // do something based on img.width and/or img.height
    }, 0);
});

我不能说为什么onload事件即使从缓存加载图像时也会触发(改进了jQuery 1.4/1.5?) -但如果你仍然遇到这个问题,可能是我的答案和var src = img.src;img。SRC = "";img。SRC = SRC;技巧是有用的。

(请注意,就我的目的而言,我不关心图像属性或CSS样式中的预定义维度——但根据Xavi的回答,您可能想要删除这些维度。或者克隆图像。)