2008-10-13 15 views
14

que tiene una etiqueta img en mi aplicación web que utiliza el controlador onLoad para redimensionar la imagen:img proceso de carga no funciona bien en IE7

<img onLoad="SizeImage(this);" src="foo" > 

Esto funciona bien en Firefox 3, pero no en IE7 porque el El objeto de imagen que se pasa a la función SizeImage() tiene un ancho y una altura de 0 por alguna razón, tal vez IE llama a la función antes de que termine de cargarse. Al investigar esto, descubrí que otras personas han tenido este mismo problema con IE. También he descubierto que esto no es válida HTML 4. Este es nuestro tipo de documento, por lo que no sé si es válido o no:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 

¿Existe una solución razonable para cambiar el tamaño de una imagen, ya que es cargada , preferiblemente uno que cumpla con los estándares? La imagen se está utilizando para que el usuario cargue una foto de sí mismo, que puede ser de cualquier tamaño, y queremos mostrarla a un máximo de 150x150. Si su solución es redimensionar la imagen del servidor al cargar, sé que es la solución correcta, pero tengo prohibido implementarla :(Debe hacerse en el lado del cliente, y debe hacerse en la pantalla.

. gracias

Editar: Debido a la estructura de nuestra aplicación, no es práctico (rozando la imposible) para ejecutar este script en el proceso de carga del documento que puedo editar única forma razonable la etiqueta de la imagen y el código cerca de él (por. Por ejemplo, podría agregar un <script> justo debajo de él). Además, ya tenemos las bibliotecas Prototype y EXT JS ... la administración preferiría no tener que agregar otra (algunas respuestas han sugerido jQuery). Si esto se puede resolver usando esos marcos, eso sería genial.

Edit 2: Desafortunadamente, debemos admitir Firefox 3, IE 6 e IE 7. Es deseable admitir todos los navegadores basados ​​en Webkit, pero como nuestro sitio no los admite actualmente, podemos tolerar soluciones que solo funcionan en Big 3.

+0

Pregunta: se SizeImage() simplemente cambiando el tamaño del la imagen a 150x150? Tengo diferentes soluciones, ambas mejores que las siguientes, pero depende de lo que necesite SizeImage() para hacer. –

+0

@Eric: no, debe mantener la relación de aspecto de la imagen. Además, si la imagen original es más pequeña que 150x150, no se debe hacer ningún cambio de tamaño (no quiero estirar nunca la imagen). – rmeador

Respuesta

6

IE7 está intentando cambiar el tamaño de la imagen antes de que el árbol DOM se represente por completo. Necesitas ejecutarlo en document.onload ... solo necesitarás asegurarte de que tu función pueda manejar el pasar una referencia al elemento que no es "esto".

Alternativamente ... y espero que esto no sea una ofensa flameable ... jQuery hace que cosas como esta sean realmente, muy fáciles.

EDITAR en respuesta a EDIT 1:

Usted puede poner en cualquier document.onload(runFunction); etiqueta script, en cualquier parte del cuerpo. aún esperará hasta que el documento se cargue para ejecutar la función.

+0

por lo general, tratando de modificar una parte de la dom antes de su carga causará el temido mensaje de "operación abortada". – StingyJack

+0

@Steve, ¿cómo es "realmente fácil" hacer con jQuery?Estoy usando jQuery en mi proyecto, ¡pero esto no es más fácil! La documentación de jQuery acepta que IE no procesa onLoad correctamente incluso con el evento de carga jQuery/Ver [enlace] (http://api.jquery.com/load-event/) - párrafo "Advertencias del evento de carga cuando se usa con imágenes . ". Usé jQuery pero aún tuve que escribir un fragmento de código para soportar IE. – Fred

2

La forma en que lo haría es utilizar jQuery para hacer algo como:

$(document).load(function(){ 
    // applies to all images, could be replaced 
    //by img.resize to resize all images with class="resize" 
    $('img').each(function(){ 
     // sizing code here 
    }); 
}); 

Pero no soy un experto en javascript;)

7

Si usted no tiene que soportar IE 6, puedes usar este CSS

yourImageSelector { 
    max-width: 150px; 
    max-height: 150px; 
} 
+0

Esa es una muy buena idea ... Ni siquiera sabía que era una opción de CSS disponible. Desafortunadamente, necesitamos soportar IE6. Actualicé la pregunta para mencionar eso. – rmeador

+4

Aquí se muestra cómo admitir IE6: casey

1

setTimeout() puede ser una solución si realmente está atascado. Simplemente configúralo durante 2 o 3 segundos, o después de que se espera que la página se cargue.

EDITAR: Es posible que desee echar un vistazo a this article - todo el camino en la parte inferior sobre IE mem leak ...

4

Me he dado cuenta de que Firefox y Safari disparan eventos de "carga" en nuevas imágenes sin importar qué, pero IE 6 & 7 solo disparan "carga" si realmente tienen que obtener la imagen del servidor. 't si la imagen ya está en la memoria caché local. He jugado con dos soluciones:

1) dar la imagen de un argumento http única cada vez que el servidor web ignora, como

<img src="mypicture.jpg?keepfresh=12345" /> 

Esto tiene la desventaja de que en realidad vence el almacenamiento en caché, por lo que estamos desperdiciando ancho de banda. Pero podría resolver el problema sin tener que usar tu JavaScript.

2) En mi aplicación, las imágenes que necesitan manejadores de carga se insertan dinámicamente por JavaScript. En lugar de simplemente añadiendo la imagen, entonces la construcción de un controlador, utilizo este código, que se probó bien en Safari, FF, y IE6 & 7.

document.body.appendChild(newPicture); 
if(newPicture.complete){ 
    doStuff.apply(newPicture); 
}else{ 
    YAHOO.util.Event.addListener(newPicture, "load", doStuff); 
} 

estoy usando YUI (obviamente) pero se puede attache el manejador que usa lo que sea que funcione en su marco. La función doStuff espera ejecutarse con este adjunto al elemento IMG afectado, es por eso que lo llamo en el . Apply estilo, su kilometraje puede variar.

+0

¡Muchas gracias por esta respuesta! ¡Nunca hubiera pensado en esto yo mismo! –

+0

Gracias. Estaba teniendo problemas irritantes con un cargador de recursos en un juego HTML5 ... (altura probada> 0 en lugar de completa, pero la misma idea) –

1

Editar: Debido a la estructura de nuestra aplicación, no es práctico (rozando la imposible) para ejecutar este script en el proceso de carga del documento .

Siempre es posible agregar controladores a window.onload (o cualquier evento en realidad), aunque otros marcos, biblioteca o código concede a los manipuladores de ese evento.

<script type="text/javascript"> 
function addOnloadHandler(func) { 
    if (window.onload) { 
     var windowOnload = window.onload; 
     window.onload = function(evt) { 
      windowOnload(evt); 
      func(evt); 
     } 
    } else { 
     window.onload = function(evt) { 
      func(evt); 
     } 
    } 
} 

// attach a handler to window.onload as you normally might 
window.onload = function() { alert('Watch'); }; 

// demonstrate that you can now attach as many other handlers 
// to the onload event as you want 
addOnloadHandler(function() { alert('as'); }); 
addOnloadHandler(function() { alert('window.onload'); }); 
addOnloadHandler(function() { alert('runs'); }); 
addOnloadHandler(function() { alert('as'); }); 
addOnloadHandler(function() { alert('many'); }); 
addOnloadHandler(function() { alert('handlers'); }); 
addOnloadHandler(function() { alert('as'); }); 
addOnloadHandler(function() { alert('you'); }); 
addOnloadHandler(function() { alert('want.'); }); 
</script> 

This answer tiene una versión ligeramente diferente de mi código addOnloadHandler() usando attachEvent. Pero descubrí en las pruebas que attachEvent no parece garantizar que los controladores disparen en el orden en que los agregó, lo que puede ser importante. La función como se presenta garantiza que los manejadores se disparen en el orden agregado.

Tenga en cuenta que paso evt en los controladores de eventos agregados. Esto no es estrictamente necesario y el código debería funcionar sin él, pero trabajo con una biblioteca que espera que el evento pase al controlador onload y ese código falla a menos que lo incluya en mi función.

3

Código para jQuery. Pero es fácil marcar con otros marcos. De mucha ayuda.

var onload = function(){ /** your awesome onload method **/ }; 
var img = new Image(); 
img.src = 'test.png'; 

// IE 7 workarond 
if($.browser.version.substr(0,1) == 7){ 
    function testImg(){ 
     if(img.complete != null && img.complete == true){ 
      onload(); 
      return; 
     } 
     setTimeout(testImg, 1000); 
    } 
    setTimeout(testImg, 1000); 
}else{ 
    img.onload = onload 
} 
0

Usted puede hacer algo como:

var img = new Image(); 
img.src = '/output/preview_image.jpg' + '?' + Math.random(); 
img.onload = function() { 
    alert('pass') 
} 
Cuestiones relacionadas