281 votes

Obtenir la largeur et la hauteur réelles d'une image avec JavaScript ? (dans Safari/Chrome)

Je suis en train de créer un plugin jQuery.

Comment obtenir la largeur et la hauteur réelles de l'image avec Javascript dans Safari ?

Ce qui suit fonctionne avec Firefox 3, IE7 et 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();

Mais dans les navigateurs Webkit comme Safari et Google Chrome, les valeurs sont de 0.

4 votes

La réponse acceptée utilise l'événement de chargement de l'image. C'est tout à fait logique, mais cela s'avère être une solution peu fiable dans les situations où les images peuvent être mises en cache (à mon grand désarroi).

0 votes

Mon point de vue sur ce sujet peut vous aider, testé dans la dernière version de Webkit. stackoverflow.com/questions/318630/

5 votes

@Nosredna, vous pourriez être intéressé par le imagesLoaded qui se déclenchera même si les images ont été mises en cache.

355voto

Xavi Points 9768

Les navigateurs Webkit définissent les propriétés hauteur et largeur après le chargement de l'image. Au lieu d'utiliser des délais d'attente, je vous recommande d'utiliser l'événement onload d'une image. Voici un exemple rapide :

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

Pour éviter les effets que CSS pourrait avoir sur les dimensions de l'image, le code ci-dessus fait une copie en mémoire de l'image. Il s'agit d'une solution très astucieuse suggérée par FDisk .

Vous pouvez également utiliser le naturalHeight et naturalWidth Attributs HTML5.

2 votes

Je teste sur Firefox 3 et $(document).ready() ne fonctionne pas non plus aussi bien.

5 votes

C'est astucieux, je ne savais pas qu'on pouvait faire $(img).load() ;

1 votes

Sur certains navigateurs, le chargement ne se fait pas sur une image en cache (ce qui me rend triste). Opera, par exemple. Mais Opera revient immédiatement à une largeur et une hauteur correctes, donc vous pouvez contourner ce problème. Malheureusement, le dernier Chrome sur ma machine semble souffrir du même problème, donc je dirais que cette solution n'est pas fiable.

289voto

sandstrom Points 2420

Utilisez le naturalHeight et naturalWidth attributs de HTML5 .

Par exemple :

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

Fonctionne dans IE9+, Chrome, Firefox, Safari et Opera ( stats ).

3 votes

@DavidJohnstone Un exemple de leur utilisation pourrait aider. Mais je suis d'accord, il mériterait d'être plus haut placé.

5 votes

Cela ne semble pas fonctionner dans la dernière version de FireFox (30.0), sauf si l'image existe déjà dans le cache.

1 votes

Je suis d'accord avec David Johnstone. C'est une excellente nouvelle.

62voto

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

Vous n'avez pas besoin de supprimer le style des attributs image ou dimensions de l'image. Il suffit de créer un élément avec javascript et de récupérer la largeur de l'objet créé.

3 votes

Depuis quelques mois, cloner une image avec jquery (en utilisant la dernière version de Chrome) et obtenir ses propriétés, renvoie toujours 0x0 Jusqu'à présent, c'est la seule solution qui fonctionne (j'ai testé toutes les autres dans cette page) Avant de retourner, j'ai mis t=null aussi.

1 votes

FDisk ne suggère pas de cloner l'image avec jQuery. Il suggère de créer une nouvelle Image puis en regardant son width propriété. Il s'agit d'une approche simple et élégante. FDisk, vous avez mon vote :)

3 votes

Il s'agit d'un moyen très astucieux d'éviter les problèmes de css. Malheureusement, la solution décrite ci-dessus ne fonctionnera que si l'image est mise en cache ou si son téléchargement est déjà terminé. Si l'image n'est pas mise en cache ou si ce code est appelé avant window.onload une largeur de 0 pourrait être retournée.

17voto

JKS Points 1584

Il y a beaucoup de discussion dans la réponse acceptée à propos d'un problème où le onload ne se déclenche pas si une image est chargée depuis le cache de WebKit.

Dans mon cas, onload se déclenche pour les images mises en cache, mais la hauteur et la largeur sont toujours de 0. Un simple setTimeout a résolu le problème pour moi :

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

Je ne peux pas dire pourquoi le onload se déclenche même lorsque l'image est chargée à partir de la mémoire cache (amélioration de jQuery 1.4/1.5 ?) - mais si vous rencontrez toujours ce problème, peut-être qu'une combinaison de ma réponse et de l'événement var src = img.src; img.src = ""; img.src = src; Cette technique fonctionnera.

(Notez que pour mes besoins, je ne suis pas concerné par les dimensions prédéfinies, que ce soit dans les attributs de l'image ou dans les styles CSS - mais vous pourriez vouloir les supprimer, conformément à la réponse de Xavi. Ou cloner l'image).

0 votes

J'ai eu ce même problème avec IE7 et IE8. setTimeout() a fonctionné pour moi pour ces navigateurs. Merci !

15voto

Cugel Points 279

Le problème de base est que les navigateurs WebKit (Safari et Chrome) chargent les informations JavaScript et CSS en parallèle. Ainsi, JavaScript peut s'exécuter avant que les effets de style de CSS aient été calculés, renvoyant une réponse erronée. En jQuery, j'ai trouvé que la solution est d'attendre que document.readyState == 'complete', par exemple,

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

En ce qui concerne la largeur et la hauteur... selon ce que vous faites, vous pouvez vouloir un offsetWidth et un offsetHeight, qui incluent des éléments tels que les bordures et le rembourrage.

0 votes

Oui, c'est la raison. Une meilleure solution est d'utiliser le load-event de jQuery.

6 votes

$(window).load(function(){ ... }); a aidé dans mon cas

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X