javascript - source - w3schools browser
img onload no funciona bien en IE7 (8)
IE7 está tratando de 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 cosas como esta realmente, muy fáciles.
EDIT en respuesta a EDIT 1:
Puede poner document.onload(runFunction);
en cualquier etiqueta de script, en cualquier parte del cuerpo. aún esperará hasta que el documento se cargue para ejecutar la función.
Tengo una etiqueta img en mi aplicación web que usa el controlador de carga para cambiar el tamaño de la imagen:
<img onLoad="SizeImage(this);" src="foo" >
Esto funciona bien en Firefox 3, pero falla en IE7 porque el objeto de imagen que se pasa a la función SizeImage()
tiene un ancho y alto de 0 por alguna razón, ¿tal vez IE llama a la función antes de que termine de cargar ?. Al investigar esto, descubrí que otras personas han tenido este mismo problema con IE. También descubrí que este no es un HTML 4. Este es nuestro doctype, 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 a medida que se carga, preferiblemente una 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 en un máximo de 150x150. Si su solución es redimensionar la imagen del lado del servidor al cargarla, sé que es la solución correcta, pero tengo prohibido implementarla :( Debe hacerse desde el lado del cliente, y debe hacerse en la pantalla.
Gracias.
Editar : Debido a la estructura de nuestra aplicación, no es práctico (casi imposible) ejecutar este script en la carga del documento. Solo puedo editar razonablemente la etiqueta de la imagen y el código cerca de ella (por ejemplo, podría agregar un <script>
justo debajo de ella). 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, sería genial.
Editar 2 : Desafortunadamente, debemos admitir Firefox 3, IE 6 e IE 7. También es deseable admitir todos los navegadores basados en Webkit, pero como nuestro sitio no los admite actualmente, podemos tolerar soluciones que solo funcionan en el Big 3.
La forma en que lo haría es usar 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;)
Si no tiene que admitir IE 6, puede usar este CSS.
yourImageSelector {
max-width: 150px;
max-height: 150px;
}
setTimeout () puede ser una solución si realmente está atascado. Simplemente configúrelo 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 este artículo - todo el camino en la parte inferior sobre IE mem leaks ...
Me he dado cuenta de que Firefox y Safari activan eventos de "carga" en nuevas imágenes sin importar qué, pero IE 6 y 7 solo activan "cargar" si realmente tienen que obtener la imagen del servidor; no lo hacen si la imagen es Ya en el caché local. Jugué con dos soluciones:
1) Dale a la imagen un argumento http único cada vez, que el servidor web ignora, como
<img src="mypicture.jpg?keepfresh=12345" />
Esto tiene la desventaja de que en realidad derrota el almacenamiento en caché, por lo que está 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 agregar la imagen, luego construir un controlador, uso este código, que se prueba bien en Safari, FF e IE6 y 7.
document.body.appendChild(newPicture);
if(newPicture.complete){
doStuff.apply(newPicture);
}else{
YAHOO.util.Event.addListener(newPicture, "load", doStuff);
}
Estoy usando YUI (obviamente) pero puedes agregar el manejador usando lo que funcione en tu marco. La función doStuff espera ejecutarse con este adjunto al elemento IMG afectado, es por eso que lo llamo en el estilo .aplicar , su kilometraje puede variar.
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
}
Puedes hacer algo como:
var img = new Image();
img.src = ''/output/preview_image.jpg'' + ''?'' + Math.random();
img.onload = function() {
alert(''pass'')
}
Editar: Debido a la estructura de nuestra aplicación, no es práctico (casi imposible) ejecutar este script en la carga del documento.
Siempre es posible agregar controladores a window.onload
(o cualquier evento en realidad), incluso si otros frameworks, bibliotecas o códigos adjuntan manejadores a 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>
Esta respuesta 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 manipuladores disparen en el orden en que los agregaste, 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 de onload
y ese código falla a menos que lo incluya en mi función.