我正在创建一个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。


当前回答

在github检查这个存储库!

使用Javascript检查宽度和高度的好例子

https://github.com/AzizAK/ImageRealSize

-编辑的要求从一些评论。

Javascript代码:

 function CheckImageSize(){
var image = document.getElementById("Image").files[0];
           createReader(image, function (w, h) {

                alert("Width is: " + w + " And Height is: "+h);
});            
}


  function  createReader(file, whenReady) {
        var reader = new FileReader;
        reader.onload = function (evt) {
            var image = new Image();
            image.onload = function (evt) {
                var width = this.width;
                var height = this.height;
                if (whenReady) whenReady(width, height);
            };
            image.src = evt.target.result;
        };
        reader.readAsDataURL(file);
    }

和HTML代码:

<html>
<head>
<title>Image Real Size</title>
<script src="ImageSize.js"></script>
</head>
<body>
<input type="file" id="Image"/>
<input type="button" value="Find the dimensions" onclick="CheckImageSize()"/>
</body>
<html>

其他回答

无意中发现了这条线索,试图为我自己的问题找到答案。我试图在加载程序后的函数中获得图像的宽度/高度,并不断得到0。我觉得这可能就是你想要的,因为这对我来说很管用:

tempObject.image = $('<img />').attr({ 'src':"images/prod-" + tempObject.id + ".png", load:preloader });
xmlProjectInfo.push(tempObject);

function preloader() {
    imagesLoaded++;
    if (imagesLoaded >= itemsToLoad) { //itemsToLoad gets set elsewhere in code
        DetachEvent(this, 'load', preloader); //function that removes event listener
        drawItems();
    }   
}

function drawItems() {
    for(var i = 1; i <= xmlProjectInfo.length; i++)
        alert(xmlProjectInfo[i - 1].image[0].width);
}

根本问题是WebKit浏览器(Safari和Chrome)并行加载JavaScript和CSS信息。因此,JavaScript可能在计算CSS的样式效果之前执行,返回错误的答案。在jQuery中,我发现解决方案是等到文档。readyState == 'complete',例如,

jQuery(document).ready(function(){
  if (jQuery.browser.safari && document.readyState != "complete"){
    //console.info('ready...');
    setTimeout( arguments.callee, 100 );
    return;
  } 
  ... (rest of function) 

至于宽度和高度……根据你正在做的事情,你可能需要offsetWidth和offsetHeight,其中包括边界和填充。

如前所述,如果图像在缓存中,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,您将不得不解析它并添加额外的参数来清除缓存。

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

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

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

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

为了补充Xavi的答案,Paul Irish的github David Desandro的gitgub提供了一个名为imagesLoaded()的函数,它的工作原理相同,并解决了一些浏览器的缓存图像不触发.load()事件的问题(使用聪明的original_src -> data_uri -> original_src切换)。

它被广泛使用并定期更新,这有助于它成为解决问题的最健壮的解决方案。