Domanda

Sto creando un plugin jQuery.

Come posso ottenere la larghezza e l'altezza dell'immagine reale con Javascript in Safari?

Di seguito funziona con Firefox 3, IE7 e 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();

Ma nei browser Webkit come Safari e Google Chrome i valori sono 0.

È stato utile?

Soluzione

I browser Webkit impostano la proprietà height e width dopo il caricamento dell'immagine. Invece di utilizzare i timeout, consiglierei di utilizzare l'evento onload di un'immagine. Ecco un breve esempio:

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

Per evitare uno qualsiasi degli effetti che CSS potrebbe avere sulle dimensioni dell'immagine, il codice sopra crea una copia in memoria dell'immagine. Questa è una soluzione molto intelligente suggerita da FDisk .

Puoi anche usare gli attributi naturalHeight e naturalWidth HTML5.

Altri suggerimenti

Utilizza gli attributi naturalHeight e naturalWidth di HTML5 .

Ad esempio:

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

Funziona in IE9 +, Chrome, Firefox, Safari e Opera ( stats ).


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

Non è necessario rimuovere lo stile dall'immagine o dagli attributi delle dimensioni dell'immagine. Basta creare un elemento con JavaScript e ottenere la larghezza dell'oggetto creato.

Il problema principale è che i browser WebKit (Safari e Chrome) caricano le informazioni JavaScript e CSS in parallelo. Pertanto, JavaScript può essere eseguito prima che gli effetti di stile del CSS siano stati calcolati, restituendo la risposta sbagliata. In jQuery, ho scoperto che la soluzione è aspettare fino a document.readyState == 'complete', .e.g.,

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

Per quanto riguarda la larghezza e l'altezza ... a seconda di ciò che stai facendo potresti volere offsetWidth e offsetHeight, che includono elementi come bordi e riempimento.

C'è molta discussione nella risposta accettata su un problema in cui l'evento onload non si attiva se un'immagine viene caricata dalla cache di WebKit.

Nel mio caso, setTimeout viene attivato per le immagini memorizzate nella cache, ma l'altezza e la larghezza sono ancora 0. Un semplice var src = img.src; img.src = ""; img.src = src; risolto il problema per me:

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

Non posso parlare del motivo per cui l'evento <=> viene generato anche quando l'immagine viene caricata dalla cache (miglioramento di jQuery 1.4 / 1.5?) & # 8212; ma se continui a riscontrare questo problema, forse una combinazione della mia risposta e della <=> tecnica funzionerà.

(Nota che per i miei scopi, non sono preoccupato per le dimensioni predefinite, né negli attributi dell'immagine o negli stili CSS & # 8212; ma potresti volerli rimuovere, secondo la risposta di Xavi. O clone l'immagine.)

questo funziona per me (safari 3.2) sparando dall'evento window.onload:

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

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

  alert( pic.width() );
  alert( pic.height() );
});

Puoi ottenere a livello di codice l'immagine e controllare le dimensioni usando Javascript senza dover fare confusione con il 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';

Che dire di image.naturalHeight e image.naturalWidth proprietà?

Sembra funzionare bene un bel po 'di versioni in Chrome, Safari e Firefox, ma per niente in IE8 o IE9.

Come otteniamo le giuste dimensioni reali senza un'immagine reale lampeggiante:

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

Funziona con < img class = " toreaddimensions " ...

Jquery ha due proprietà chiamate naturalWidth e naturalHeight, che puoi usare in questo modo.

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

Dove my-img è un nome di classe utilizzato per selezionare la mia immagine.

Come affermato in precedenza, Xavi answer non funzionerà se le immagini sono nella cache. Il problema risponde al webkit che non attiva l'evento load sulle immagini memorizzate nella cache, quindi se l'attrs di larghezza / altezza non è impostato in modo esplicito nel tag img, l'unico modo affidabile per ottenere le immagini è attendere che l'evento window.load venga attivato .

L'evento img.src genererà sempre , quindi è sicuro accedere alla larghezza / altezza di e img dopo di ciò senza alcun trucco.

$(window).load(function(){

   //these all work

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

});

Se è necessario ottenere le dimensioni delle immagini caricate dinamicamente che potrebbero essere memorizzate nella cache (precedentemente caricate), è possibile utilizzare il metodo Xavi più una stringa di query per attivare un aggiornamento della cache. L'aspetto negativo è che causerà un'altra richiesta al server, per un img che è già memorizzato nella cache e dovrebbe essere già disponibile. Stupido 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: se hai già una QueryString in <=>, dovrai analizzalo e aggiungi il parametro extra per cancellare la cache.

Come dice Luke Smith, il caricamento dell'immagine è un casino . Non è affidabile su tutti i browser. Questo fatto mi ha fatto molto male. Un'immagine memorizzata nella cache non genererà affatto l'evento in alcuni browser, quindi coloro che hanno detto & Quot; il caricamento dell'immagine è migliore di setTimeout & Quot; sono sbagliati.

La soluzione di Luke Smith è qui.

E c'è una discussione interessante su come questo il pasticcio potrebbe essere gestito in jQuery 1.4.

Ho scoperto che è abbastanza affidabile impostare la larghezza su 0, quindi attendere " complete " la proprietà diventa true e la proprietà width diventa maggiore di zero. Dovresti anche cercare errori.

$("#myImg").one("load",function(){
  //do something, like getting image width/height
}).each(function(){
  if(this.complete) $(this).trigger("load");
});

Dal commento di Chris: http://api.jquery.com/load-event/

La mia situazione è probabilmente un po 'diversa. Sto cambiando dinamicamente l'src di un'immagine tramite javascript e ho bisogno di assicurarmi che la nuova immagine sia dimensionata proporzionalmente per adattarsi a un contenitore fisso (in una galleria fotografica). Inizialmente ho appena rimosso gli attributi di larghezza e altezza dell'immagine dopo che è stata caricata (tramite l'evento di caricamento dell'immagine) e li ho ripristinati dopo aver calcolato le dimensioni preferite. Tuttavia, ciò non funziona in Safari e probabilmente IE (non l'ho testato a fondo in IE, ma l'immagine non viene nemmeno mostrata, quindi ...).

Comunque, Safari mantiene le dimensioni dell'immagine precedente in modo che le dimensioni siano sempre un'immagine indietro. Presumo che questo abbia qualcosa a che fare con la cache. Quindi la soluzione più semplice è semplicemente clonare l'immagine e aggiungerla al DOM (è importante che sia aggiunta al DOM al fine di ottenere l'altezza e l'altezza). Dai all'immagine un valore di visibilità nascosto (non usare display none perché non funzionerà). Dopo aver ottenuto le dimensioni rimuovere il clone.

Ecco il mio codice usando 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);

Questa soluzione funziona in ogni caso.

Ora c'è un plug-in jQuery, event.special.load, per gestire i casi in cui l'evento load su un'immagine memorizzata nella cache non viene generato: http://github.com/peol/jquery.imgloaded/raw/master/ahpi.imgload.js

Recentemente ho dovuto trovare la larghezza e l'altezza per impostare la dimensione predefinita di .dialog che rappresenta il grafico. La soluzione che uso era:

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

Per me funziona in FF3, Opera 10, IE 8,7,6

P.S. Potresti trovare altre soluzioni guardando all'interno di alcuni plugin come LightBox o ColorBox

Per aggiungere alla risposta di Xavi, Github di Paul Irish Il gitgub di David Desandro offre una funzione chiamata imagesLoaded () che funziona con gli stessi principi e aggira il problema delle immagini memorizzate nella cache di alcuni browser non attivare l'evento .load () (con Cle_ original_src - > data_uri - > commutazione original_src).

È ampiamente utilizzato e aggiornato regolarmente, il che contribuisce a renderlo la soluzione più solida al problema, IMO.

Funziona sia con immagini memorizzate nella cache sia caricate dinamicamente.

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

Per utilizzare questo script:

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

Demo: http://jsfiddle.net/9543z/2/

Ho svolto alcune funzioni di utilità alternativa, usando il plug-in jquery di imagesLoaded: 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}));
            },

Puoi usarlo passando url, funzione e il suo contesto. La funzione viene eseguita dopo che l'immagine è stata caricata e restituisce l'immagine creata, la sua larghezza e altezza.

waitForImageSize("image.png", function(w,h){alert(w+","+h)},this)

Se l'immagine è già utilizzata, sholud:

  1. imposta le simulazioni delle immagini su iniziali

    image.css ('larghezza', 'iniziale'); image.css ('altezza', 'iniziale');

  2. ottieni dimensioni

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

È possibile utilizzare le proprietà naturalWidth e naturalHeight dell'elemento immagine HTML. (Ecco altre info ).

Lo useresti in questo modo:

//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;

Sembra che funzioni in tutti i browser tranne su Internet Explorer dalla versione 8 in poi.

Per le funzioni in cui non si desidera modificare la posizione o l'immagine originale.

$(this).clone().removeAttr("width").attr("width");
$(this).clone().removeAttr("height").attr("height);

Ho verificato la risposta di Dio e per me funziona benissimo.

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

Assicurati di chiamare anche tutte le tue funzioni. che gestiscono con le dimensioni dell'immagine nella funzione di richiamo di fadeIn ().

Grazie per questo.

Uso un approccio diverso, faccio semplicemente una chiamata Ajax al server per ottenere la dimensione dell'immagine quando l'oggetto image è in uso.

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

e ovviamente il codice lato server:

<?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);

?>

Funziona su più browser

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

ottieni le dimensioni usando

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

Cheers!

Un altro suggerimento è quello di utilizzare plugin di ImageLoaded .

$("img").imagesLoaded(function(){
alert( $(this).width() );
alert( $(this).height() );
});
$(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);
                            }
                        }); 

// Questo codice aiuta a mostrare l'immagine con una dimensione di 200 * 274

Ecco una soluzione cross-browser che attiva un evento quando vengono caricate le immagini selezionate: http: //desandro.github .io / imagesloaded / puoi cercare l'altezza e la larghezza all'interno della funzione imagesLoaded ().

Ci siamo imbattuti in questa discussione cercando di trovare una risposta per la mia domanda. Stavo cercando di ottenere una larghezza / altezza di un'immagine in una funzione DOPO il caricatore, e continuavo a venire con 0. Sento che questo potrebbe essere quello che stai cercando, tuttavia, poiché funziona per me:

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

Dai un'occhiata a questo repository in github!

Ottimo esempio per controllare la larghezza e l'altezza usando Javascript

https://github.com/AzizAK/ImageRealSize

--- Modificato è richiesto da alcuni commenti ..

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

e codice 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>
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top