282

我正在创建一个 jQuery 插件。

如何在 Safari 中使用 Javascript 获取真实的图像宽度和高度?

以下适用于 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 和 Google Chrome 等 Webkit 浏览器中,值为 0。

4

30 回答 30

357

Webkit 浏览器在加载图像后设置 height 和 width 属性。我建议不要使用超时,而是使用图像的 onload 事件。这是一个简单的例子:

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.
    });

为了避免 CSS 可能对图像尺寸产生任何影响,上面的代码在内存中创建了图像的副本。这是FDisk提出的一个非常聪明的解决方案。

您还可以使用naturalHeightnaturalWidthHTML5 属性。

于 2009-03-22T02:19:35.523 回答
289

使用HTML5naturalHeight中的和naturalWidth属性。

例如:

var h = document.querySelector('img').naturalHeight;

适用于 IE9+、Chrome、Firefox、Safari 和 Opera ( stats )。

于 2011-06-20T15:27:34.133 回答
62


function getOriginalWidthOfImg(img_element) {
    var t = new Image();
    t.src = (img_element.getAttribute ? img_element.getAttribute("src") : false) || img_element.src;
    return t.width;
}

您不需要从图像或图像尺寸属性中删除样式。只需使用 javascript 创建一个元素并获取创建的对象宽度。

于 2010-07-07T07:00:58.590 回答
17

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

就我而言,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 的回答删除这些尺寸。或者克隆图像。)

于 2011-02-05T19:42:18.303 回答
16

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

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

就宽度和高度而言...取决于您在做什么,您可能需要 offsetWidth 和 offsetHeight,其中包括边框和填充等内容。

于 2008-11-25T20:47:47.897 回答
11

通过从window.onload事件内部触发,这对我有用(safari 3.2):

$(window).load(function() {
  var pic = $('img');

  pic.removeAttr("width"); 
  pic.removeAttr("height");

  alert( pic.width() );
  alert( pic.height() );
});
于 2008-11-25T20:16:29.693 回答
8

您可以使用 Javascript 以编程方式获取图像并检查尺寸,而无需完全弄乱 DOM。

var img = new Image();
img.onload = function() {
  console.log(this.width + 'x' + this.height);
}
img.src = 'http://www.google.com/intl/en_ALL/images/logo.gif';
于 2012-05-31T21:15:55.480 回答
7

image.naturalHeightimage.naturalWidth属性呢?

似乎在 Chrome、Safari 和 Firefox 中的很多版本都可以正常工作,但在 IE8 甚至 IE9 中根本不行。

于 2012-01-03T18:54:42.060 回答
6

Jquery 有两个属性叫做 naturalWidth 和 naturalHeight,你可以这样使用。

$('.my-img')[0].naturalWidth 
$('.my-img')[0].naturalHeight

其中 my-img 是用于选择我的图像的类名。

于 2015-08-02T20:29:03.023 回答
5

我们如何在不闪烁真实图像的情况下获得正确的真实尺寸:

(function( $ ){
   $.fn.getDimensions=function(){
         alert("First example:This works only for HTML code without CSS width/height definition.");
         w=$(this, 'img')[0].width;
         h=$(this, 'img')[0].height;

         alert("This is a width/height on your monitor: " + $(this, 'img')[0].width+"/"+$(this, 'img')[0].height);

         //This is bad practice - it shows on your monitor
         $(this, 'img')[0].removeAttribute( "width" );
         $(this, 'img')[0].removeAttribute( "height" );
         alert("This is a bad effect of view after attributes removing, but we get right dimensions: "+  $(this, 'img')[0].width+"/"+$(this, 'img')[0].height);
         //I'am going to repare it
         $(this, 'img')[0].width=w;
         $(this, 'img')[0].height=h;
         //This is a good practice - it doesn't show on your monitor
         ku=$(this, 'img').clone(); //We will work with a clone
         ku.attr( "id","mnbv1lk87jhy0utrd" );//Markup clone for a final removing
         ku[0].removeAttribute( "width" );
         ku[0].removeAttribute( "height" );
         //Now we still get 0
         alert("There are still 0 before a clone appending to document: "+ $(ku)[0].width+"/"+$(ku)[0].height);
         //Hide a clone
         ku.css({"visibility" : "hidden",'position':'absolute','left':'-9999px'}); 
         //A clone appending
         $(document.body).append (ku[0]);
         alert("We get right dimensions: "+ $(ku)[0].width+"/"+$(ku)[0].height);
         //Remove a clone
         $("#mnbv1lk87jhy0utrd").remove();

         //But a next resolution is the best of all. It works in case of CSS definition of dimensions as well.
         alert("But if you want to read real dimensions for image with CSS class definition outside of img element, you can't do it with a clone of image. Clone method is working with CSS dimensions, a clone has dimensions as well as in CSS class. That's why you have to work with a new img element.");
         imgcopy=$('<img src="'+ $(this, 'img').attr('src') +'" />');//new object 
         imgcopy.attr( "id","mnbv1lk87jhy0aaa" );//Markup for a final removing
         imgcopy.css({"visibility" : "hidden",'position':'absolute','left':'-9999px'});//hide copy 
         $(document.body).append (imgcopy);//append to document 
         alert("We get right dimensions: "+ imgcopy.width()+"/"+imgcopy.height());
         $("#mnbv1lk87jhy0aaa").remove();


   }
})( jQuery );

$(document).ready(function(){

   $("img.toreaddimensions").click(function(){$(this).getDimensions();});
});

它适用于 <img class="toreaddimensions"...

于 2010-12-02T07:07:38.883 回答
3

如前所述,如果图像在缓存中,Xavi 答案将不起作用。该问题响应 webkit 未触发缓存图像的加载事件,因此如果未在 img 标记中明确设置宽度/高度属性,则获取图像的唯一可靠方法是等待window.load触发事件。

window.load事件将始终触发,因此无需任何技巧即可安全地访问和 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:如果你已经有一个QueryString img.src,你将不得不解析它并添加额外的参数来清除缓存。

于 2011-09-27T17:09:04.450 回答
2

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

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

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

我发现将宽度设置为 0 非常可靠,然后等待“完成”属性变为真并且宽度属性大于零。你也应该注意错误。

于 2009-11-06T15:22:04.160 回答
2
$("#myImg").one("load",function(){
  //do something, like getting image width/height
}).each(function(){
  if(this.complete) $(this).trigger("load");
});

来自克里斯的评论:http ://api.jquery.com/load-event/

于 2010-07-09T21:39:54.820 回答
2

我的情况可能有点不同。我正在通过 javascript 动态更改图像的 src,并且需要确保新图像的大小按比例调整以适合固定容器(在照片库中)。我最初只是在加载图像后(通过图像的加载事件)删除了图像的宽度和高度属性,并在计算出首选尺寸后重置这些属性。但是,这在 Safari 和可能的 IE 中不起作用(我没有在 IE 中彻底测试过它,但图像甚至没有显示,所以......)。

无论如何,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);

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

于 2012-11-01T00:59:26.870 回答
1

现在有一个 jQuery 插件,event.special.load用于处理缓存图像上的加载事件不触发的情况:http: //github.com/peol/jquery.imgloaded/raw/master/ahpi.imgload.js

于 2010-09-24T22:47:53.470 回答
1

最近我需要找到宽度和高度来设置 .dialog 表示图形的默认大小。我使用的解决方案是:

 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 })
    })

对我来说,这适用于 FF3、Opera 10、IE 8、7、6

PS 您可能会在 LightBox 或 ColorBox 等插件中找到更多解决方案

于 2011-01-26T17:30:59.093 回答
1

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

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

于 2011-08-16T20:00:02.290 回答
1

这适用于缓存和动态加载的图像。

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/

于 2012-02-20T12:45:48.133 回答
1

我已经使用 imagesLoaded jquery 插件完成了一些解决方法实用功能: 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}));
            },

您可以通过传递 url、函数及其上下文来使用它。加载图像后执行函数并返回创建的图像,其宽度和高度。

waitForImageSize("image.png", function(w,h){alert(w+","+h)},this)
于 2012-04-19T08:04:58.400 回答
1

如果图像已被使用,您应该:

  1. 将图像尺寸设置为初始值

    image.css('宽度', '初始'); image.css('高度', '初始');

  2. 获取尺寸

    var originalWidth = $(this).width(); var originalHeight = $(this).height();

于 2014-02-26T05:40:26.377 回答
1

您可以使用 HTML 图像元素的 naturalWidth 和 naturalHeight 属性。(这里有更多信息)。

你会像这样使用它:

//you need a reference to the DOM element, not a jQuery object. It would be better if you can use document.getElementByTagsName or ID or any other native method
var pic = $("img")[0];
var pic_real_width = pic.naturalWidth;
var pic_real_height = pic.naturalHeight;

似乎这适用于所有浏览器,但 IE 版本 8 及以下版本除外。

于 2017-12-14T22:43:43.087 回答
0

我查看了 Dio 的答案,它对我很有用。

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

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

谢谢你。

于 2010-12-14T09:49:39.810 回答
0

我使用不同的方法,只需在使用图像对象时对服务器进行 Ajax 调用以获取图像大小。

//make json call to server to get image size
$.getJSON("http://server/getimagesize.php",
{"src":url},
SetImageWidth
);

//callback function
function SetImageWidth(data) {

    var wrap = $("div#image_gallery #image_wrap");

    //remove height
     wrap.find("img").removeAttr('height');
    //remove height
     wrap.find("img").removeAttr('width');

    //set image width
    if (data.width > 635) {
        wrap.find("img").width(635);
    }
    else {
         wrap.find("img").width(data.width);
    }
}

当然还有服务器端代码:

<?php

$image_width = 0;
$image_height = 0;

if (isset ($_REQUEST['src']) && is_file($_SERVER['DOCUMENT_ROOT'] . $_REQUEST['src'])) {

    $imageinfo = getimagesize($_SERVER['DOCUMENT_ROOT'].$_REQUEST['src']);
    if ($imageinfo) {
       $image_width=  $imageinfo[0];
       $image_height= $imageinfo[1];
    }
}

$arr = array ('width'=>$image_width,'height'=>$image_height);

echo json_encode($arr);

?>
于 2010-12-17T10:07:57.523 回答
0

另一个建议是使用imagesLoaded 插件

$("img").imagesLoaded(function(){
alert( $(this).width() );
alert( $(this).height() );
});
于 2011-12-10T11:04:05.693 回答
0

这适用于跨浏览器

var img = new Image();
$(img).bind('load error', function(e)
{
    $.data(img, 'dimensions', { 'width': img.width, 'height': img.height });                    
});
img.src = imgs[i];              

通过使用获取尺寸

$(this).data('dimensions').width;
$(this).data('dimensions').height;

干杯!

于 2012-01-03T05:19:36.563 回答
0
$(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);
                            }
                        }); 

// 此代码有助于显示 200*274 尺寸的图像

于 2012-08-03T05:11:25.770 回答
0

这是一个跨浏览器解决方案,当您选择的图像被加载时触发一个事件:http: //desandro.github.io/imagesloaded/您可以在 imagesLoaded() 函数中查找高度和宽度。

于 2013-05-01T20:22:12.567 回答
0

偶然发现这个线程试图为我自己的问题找到答案。我试图在加载程序之后的函数中获取图像的宽度/高度,并不断提出 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);
}
于 2013-09-11T20:34:10.237 回答
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>
于 2015-11-30T07:37:02.820 回答
-1

对于您不想更改原始位置或图像的功能。

$(this).clone().removeAttr("width").attr("width");
$(this).clone().removeAttr("height").attr("height);
于 2009-08-27T15:04:39.550 回答