2009-12-09 26 views
7

Actualmente estoy desarrollando pruebas unitarias para un método Javascript que detecta la preparación del documento. Este código ya se encuentra en el nivel del marco, por lo tanto, evite mencionar que esto ya está implementado en jQuery u otra biblioteca.Cómo iniciar el evento "onload" en el documento en IE

He simulado con éxito el evento de cambio 'ReadyStateChange' con el siguiente código:

var event; 
event = document.createEventObject(); 
event.type = 'readystatechange'; 
document.fireEvent('onreadystatechange',event); 

que no pudieron hacer lo mismo para el caso de 'carga'. Los código siguiente produce un error argumento no válido en IE7, lanzada por la llamada a fireEvent en la última línea:

event = document.createEventObject(); 
event.type = 'load'; 
document.fireEvent('onload',event); 

Alguien ha hecho esto, o dejado de hacer esto antes? También estoy interesado en cualquier sugerencia de despedir el evento de una manera diferente.

Editar: siguiendo la sugerencia de la Media Luna fresca, he cambiado mi código para:

event = document.createEventObject(); 
event.type = 'load'; 
document.body.fireEvent('onload',event); 

Ya no hay error, pero el oyente de 'onLoad' no se dispara. Así es como yo configuré:

document.attachEvent('onload',listener); 
+1

El evento 'load' en realidad se activa en' document.body'. Entonces puede intentar en su lugar 'document.body.fireEvent ('onload', event)'. Sin embargo, dudo que vaya a disparar mangos conectados a 'onload'. Si lo hiciera, me sorprendería ... –

+0

Estás 100% en lo cierto. Se puede ejecutar el evento en document.body sin error, pero los oyentes adjuntos con document.attachEvent no se activan. –

+0

@Eric: pensé mucho. Es un hombre malo. –

Respuesta

4

Según this page at MSDN, no hay evento onload para document.

Desea window.onload o document.body.onload. Estos son idénticos en IE: por razones históricas, <body onload="..."> en realidad establece window.onload, por lo que MS decidió hacer document.body.onload un alias de window.onload.

El problema con esto es que, como Eric mencionó en los comentarios, no parece que haya una forma de activar manualmente los eventos de la ventana, lo que significa que podría no haber una solución para el problema de Eric.

+1

@Christoph: buen punto, ya mencionado por Crescent Fresh: Debería iniciar el evento en document.body en su lugar. Interesante comentario en window.onload pero no tan útil ya que window no tiene el método fireEvent. –

+0

@Christoph gracias por editar su respuesta. Lo aceptaré como conclusión de esta interesante discusión. –

0

El evento de carga se disparará cuando el documento (incluyendo los recursos externos tales como imágenes) se cargue por completo, y no antes.

¿Qué resultados obtiene de sus intentos de disparar readystatechange? ¿El valor readyState realmente cambia en absoluto? Independientemente de si eso no sirve de mucho: si activa el evento con un readyState que no ha cambiado, o lo hace con un readyState que no es un reflejo válido del estado del documento.

+0

@NickFitz Gracias por la respuesta. No estoy tratando de cambiar el valor de document.readyState, que sigue siendo 'completo' antes (porque tengo que esperar hasta que readyState se convierta en 'completo') y después de mi prueba. Tenga en cuenta que este código está escrito para pruebas unitarias. –

+0

@NickFitz: Eric solo está tratando de simular el evento 'carga' del mundo real para pruebas de unidades locales. –

+0

Si es para una prueba unitaria, entonces no debería necesitar disparar ningún evento. Simplemente cree un objeto de evento simulado con valores conocidos y llame al controlador de eventos directamente, luego verifique que produzca los resultados correctos para esos valores. De lo contrario, no es una prueba de unidad, es una prueba de integración: está probando cómo el código se integra con los mecanismos internos de manejo de eventos del navegador. – NickFitz

3

Por alguna razón, parece que IE anula la propiedad onload de window con un objeto vacío después de cargar el DOM. Al menos ese es el caso cuando se intenta acceder a él desde cualquier controlador de eventos de un elemento DOM ...

<!DOCTYPE html> 
<html> 
    <head> 
    <title>Test by Josh</title> 
    <script type="text/javascript"> 
     window.onload = function() { 
     alert("Test"); 
     } 
     alert(typeof window.onload); 
    </script> 
    </head> 
    <body> 
    <h1 onclick="alert(typeof window.onload);">Test</h1> 
    </body> 
</html> 

En esta situación, se verá que window.onload es reconocida como una función inicialmente, luego ves la alerta de "Prueba". Al hacer clic en el encabezado, verá que window.onload es ahora un object. Traté de iterar a través de las propiedades del objeto, pero está vacío. Esto no es guay.

Una solución provisional es tomar la función en el alcance accesible y asignarla a una propiedad diferente que puede disparar a su conveniencia ...

<!DOCTYPE html> 
<html> 
    <head> 
    <title>Test by Josh</title> 
    <script type="text/javascript"> 
     window.onload = function() { 
     alert("Test"); 
     }   
    </script> 
    </head> 
    <body> 
    <h1 onclick="window.onloadfix()">Test</h1> 
    <!-- Could potentially be injected via server-side include if needed --> 
    <script type="text/javascript"> 
     window.onloadfix = function() { 
     window.onload(); 
     } 
    </script> 
    </body> 
</html> 

No se me ocurre ninguna otra forma de solucionar este problema en este momento.

+0

@Josh Stodola interesante ... Hoy descubrí que document.attachEvent no es una función en IE: puede llamarlo por supuesto, pero (typeof document.attachEvent) devuelve "object" y tanto document.attachEvent.call como document. attachEvent.apply no están definidos ... este navegador nunca se detendrá para sorprenderme. –

Cuestiones relacionadas