2010-12-07 15 views
9

Necesito obtener las dimensiones de una imagen, usando una etiqueta de imagen creada dinámicamente. Funciona. SÓLO usando attr ('ancho') y SÓLO si NO agrego la imagen al DOM. De lo contrario, las dimensiones devueltas son cero. ¿Por qué? :)jQuery: la nueva imagen añadida a DOM siempre tiene el ancho 0 después de cargar

this.img = $('<img/>', {'src': e.url});   // generate image 
this.img.appendTo('body');       // add to DOM 
this.img.load(function(self){return function(){ // when loaded call function 
    console.log(self.img.attr('src')); 
    console.log(self.img.attr('width')); 
    console.log(self.img.width()); 
    console.log(self.img.css('width')); 
}; }(this));          // pass object via closure 

Así que generan la imagen, agregarlo a la DOM y definir una función de controlador que se llamará cuando se carga la imagen. Estoy usando un cierre para pasarle una referencia al objeto original, llamado "yo" dentro del cierre. Estoy volcando la URL de la imagen para asegurarme de que la referencia sea correcta. La salida es:

pic.jpg 
0 
0 
0px 

Ahora aquí es lo extraña: si quito la segunda línea de arriba (la appendTo), entonces funciona de repente, pero sólo para attr ('ancho'):

pic.jpg 
1024 
0 
0px 

Este comportamiento no tiene ningún sentido para mí. Esperaría obtener el tamaño de imagen real en los seis casos anteriores. Ahora sé cómo solucionar el problema, pero me gustaría entender por qué sucede. ¿Es un error? ¿O hay alguna razón lógica para ello?

Los resultados anteriores son para Safari. Acabo de probar con Chrome y obtuve todos los valores correctos en el primer ejemplo, pero todavía dos ceros en el segundo ejemplo. Muy raro.

+0

¿estás seguro de que siempre tienes e.url válido? – kobe

+0

@travel boy puede dar otro nombre a esta variable en lugar de img this.img, this.newImgSource o así ... /// – kobe

+0

@travelboy & gov: de acuerdo, la propiedad que contiene el objeto jQuery para la imagen debe cambiarse como img es un nombre de etiqueta, solo buenas prácticas. – UpHelix

Respuesta

3

he encontrado una solución fiable para Safari:

  • Crear la imagen
  • Fije la carga (manejador)
  • Sólo después de eso, el atributo src !!

Todavía no entiendo por qué el ancho debería volver a cero, pero parece que suceden cosas inesperadas si conecta el controlador de carga solo después de configurar el src. Tuve esa idea solo porque encontré otro problema con IE (que ni siquiera llamó al controlador de carga porque consideraba que la imagen estaba cargada antes de conectar el controlador), así que la lección que aprendí es hacer siempre cosas en el orden descrito arriba.

0

Me parece que la forma en que está asignando el objeto jQuery y llamando a la función de carga en la imagen es un poco exagerado, lo que dificulta ver por qué jQuery podría comportarse así.

Prueba esto:

this.img = $('<img />').attr('src', e.url).appendTo('body'); 
console.log('width: ' + this.img.width()); 

funciona perfectamente para mí para obtener sólo después de que la imagen se inyecta en el DOM.

También puede probar esto:

this.img = $('<img />').attr('src', e.url).css({ 
    'width': 'auto', 
    'height': 'auto' 
}).appendTo('body'); 
console.log('width: ' + this.img.width()); 
console.log('height: ' + this.img.height()); 
+0

@Dale: su enfoque seguramente fallará a menos que la imagen ya esté en el caché (porque las dimensiones se leerán antes de que se cargue la imagen). Por lo tanto, no se puede hacer de esta manera; necesita la función de carga. – travelboy

+0

Estoy de acuerdo con Travelboy, la carga asegura que la imagen se cargue en el navegador – kobe

+0

@travelboy, su código se ve perfecto, la única otra razón por la cual los elementos dan 0 es si están ocultos por alguna razón, ¿está oculto el contenedor principal de su imagen? – kobe

0

No creo que su cierre está funcionando de la manera deseada. ¿Usted ha intentado algo así como:

this.img.load(function(){       // when loaded call function 
    console.log(this.attr('src')); 
    console.log(this.attr('width')); 
    console.log(this.width()); 
    console.log(this.css('width')); 
}); 
+0

No puedo hacerlo así porque necesito una referencia al objeto que contiene img. Pero el cierre funciona (porque puedo acceder a img y a las otras propiedades del objeto) – travelboy

2

intentó su código en Firebug y cromo y se comporta como se esperaba:

var src = 'http://static.jquery.com/files/rocker/images/logo_jquery_215x53.gif'; 

this.img = $('<img/>', { 'src': src }); 
this.img.appendTo('body');       // add to DOM 
this.img.load(function(self){return function(){ // when loaded call function 
    console.log(self.img.attr('src')); 
    console.log(self.img.attr('width')); 
    console.log(self.img.width()); 
    console.log(self.img.css('width')); 
}; }(this)); 

tiene lo siguiente:

http://static.jquery.com/files/rocker/images/logo_jquery_215x53.gif 
215 
215 
215px 

después de quitar la línea appendTo() I Soy capaz de reproducir el comportamiento en Chrome, pero no me parece extraño. width() está calculando el ancho real del elemento "mostrado", p. Ej. cada vez que pones la imagen en un div oculto será == 0!

intente reemplazar la línea appendTo con la siguiente y obtendrá el mismo:

this.img.appendTo($('<div/>').css('display', 'none'));

ACTUALIZACIÓN:

Los resultados de Safari 3.1.2 están actuando exactamente lo mismo por mí como Chrome cuando se agrega a DOM.

Cuando img no se inserta en el DOM También estoy consiguiendo resultados (sin rarezas) aceptables:

http://static.jquery.com/files/rocker/images/logo_jquery_215x53.gif 
215 
0 
0px 

Estoy convencido de que debe haber algo único para su instalación ... o es una Safari @ Mac OSX error (intenté Safari en Windows env).

+0

Lo extraño es otra cosa: en Safari, la imagen tiene un ancho de cero cuando la imagen se agrega al DOM. Solo puedo leer su ancho cuando NO lo anexo al DOM. ¡Deberías encontrar eso raro! Es cierto que Chrome es comprensible. Safari no lo es. – travelboy

+0

@travelboy He actualizado mi respuesta: realmente estaba pensando en ver el comportamiento extraño en Safari, pero para mí solo funcionó de forma muy correcta ... como @gov mencionado a continuación en la configuración de Your Safari, el img podría estar oculto por alguna razón . – kares

Cuestiones relacionadas