Получить реальную ширину и высоту изображения с помощью JavaScript? (в Safari / Chrome) - PullRequest
272 голосов
/ 25 ноября 2008

Я создаю плагин 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();

Но в браузерах Webkit, таких как Safari и Google Chrome, значения равны 0.

Ответы [ 30 ]

351 голосов
/ 22 марта 2009

Браузеры Webkit устанавливают свойство высоты и ширины после загрузки изображения. Вместо использования тайм-аутов я бы рекомендовал использовать событие загрузки изображения. Вот быстрый пример:

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 .

Вы также можете использовать атрибуты naturalHeight и naturalWidth HTML5.

279 голосов
/ 20 июня 2011

Используйте атрибуты naturalHeight и naturalWidth из HTML5 .

Например:

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

Работает в IE9 +, Chrome, Firefox, Safari и Opera ( статистика ).

59 голосов
/ 07 июля 2010

<code>
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 и получите ширину созданного объекта.

16 голосов
/ 25 ноября 2008

Основная проблема заключается в том, что браузеры WebKit (Safari и Chrome) загружают информацию JavaScript и CSS параллельно. Таким образом, JavaScript может выполняться до того, как будут вычислены эффекты стиля CSS, возвращая неправильный ответ. В jQuery я обнаружил, что решение состоит в том, чтобы дождаться, пока document.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, которые включают такие вещи, как границы и отступы.

16 голосов
/ 05 февраля 2011

В принятом ответе много говорится о проблеме, при которой событие 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 - но вы можете удалить их, как указано в ответе Хави. Или клонировать изображение.)

11 голосов
/ 25 ноября 2008

это работает для меня (сафари 3.2), стреляя из события window.onload:

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

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

  alert( pic.width() );
  alert( pic.height() );
});
8 голосов
/ 01 июня 2012

Вы можете программно получить изображение и проверить размеры, используя 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';
6 голосов
/ 03 января 2012

А как насчет image.naturalHeight и image.naturalWidth свойств?

Кажется, что работает хорошо, довольно много версий в Chrome, Safari и Firefox, но не совсем в IE8 или даже IE9.

5 голосов
/ 02 декабря 2010

Как мы получаем правильные реальные размеры без мерцания реального изображения:

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

Работает с image

4 голосов
/ 02 августа 2015

Jquery имеет два свойства, называемых naturalWidth и naturalHeight, которые можно использовать таким образом.

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

Где my-img - имя класса, использованное для выбора моего изображения.

...