2010-06-24 5 views
7

Me encuentro con un problema que parece solo aparecer en Windows 7. Parecía funcionar bien en IE8 en una versión diferente de Windows. Básicamente, estoy creando una nueva ventana con window.open(), luego usando document.write() para escribir el contenido de esa nueva ventana, que contiene script. En IE, estos scripts no se están ejecutando correctamente. La mayoría de las veces no ejecutan en absoluto, pero ocasionalmente uno de ellos lo hará. Esto es solo con un caché borrado: una vez que los archivos javascript están en el caché, funciona bien.Los elementos de script escritos con document.write en una ventana abierta con window.open no se ejecutan en IE8 en Windows 7

reducía caso de prueba:

Test.html:

<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN' 'http://www.w3.org/TR/html4/loose.dtd'> 
<html> 
<head> 
    <script type="text/javascript"> 
     var w = window.open(); 
     var windowHTML = "\ 
<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN' 'http://www.w3.org/TR/html4/loose.dtd'>\n\ 
<html>\n\ 
<head>\n\ 
    <script type='text/javascript' src='test.js'></scr"+"ipt>\n\ 
    <script type='text/javascript' src='test2.js'></scr"+"ipt>\n\ 
</head>\n\ 
<body>\n\ 
</body>\n\ 
</html>"; 
     w.document.write(windowHTML); 
     w.document.close(); 
    </script> 
</head> 
<body> 
</body> 
</html> 

Test.js:

alert("test"); 

test2.js:

alert("test2"); 

Cuando voy a test.html, esperaría ver una nueva ventana w aparece con alertas para "prueba" y luego "prueba 2". Lo hago en la mayoría de los navegadores, incluido IE6. Sin embargo, cuando intento esto en IE8 en Windows 7, abre la página en blanco, pero no aparecen alertas (u ocasionalmente solo una).

¿Es algún tipo de problema de tiempo? ¿Alguien más ha visto esto? ¿Hay alguna manera de evitarlo?


Editar: Aquí está el código que he intentado Rob Cooney quería ver. Una vez más, funciona en otros navegadores, pero no en Internet Explorer 8 en Windows 7.

Test.htm:

<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN' 'http://www.w3.org/TR/html4/loose.dtd'> 
<html> 
<head> 
    <script type="text/javascript"> 
     var w = window.open(); 
     var windowHTML = 
     "<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN' 'http://www.w3.org/TR/html4/loose.dtd'>\n" + 
     "<html>\n" + 
     "<head>\n" + 
     " <script type='text/javascript' src='test.js'></scr"+"ipt>\n" + 
     " <script type='text/javascript' src='test2.js'></scr"+"ipt>\n" + 
     "</head>\n" + 
     "<body onload='test();test2()'>\n" + 
     "</body>\n" + 
     "</html>"; 
     w.document.write(windowHTML); 
     setTimeout(function() { 
     w.document.close(); 
     }, 10000); 
    </script> 
</head> 
<body> 
</body> 
</html> 

Test.js:

function test() { 
    alert("test"); 
} 

test2.js:

function test2() { 
    alert("test2"); 
} 

Además, he publicado esto como una pregunta en los foros de MSDN here.


Aceptando no hay solución como la mejor respuesta. Aquí está mi código modificado:

<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN' 'http://www.w3.org/TR/html4/loose.dtd'> 
<html> 
<head> 
    <script type="text/javascript"> 
     var w = window.open(); 
     var windowHTML = 
     "<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN' 'http://www.w3.org/TR/html4/loose.dtd'>\n" + 
     "<html>\n" + 
     "<head></head>\n" + 
     "<body></body>\n" + 
     "</html>"; 
     w.document.write(windowHTML); 
     w.document.close(); 

     var s = w.document.createElement("script"); 
     s.type = "text/javascript"; 
     s.src = "test.js"; 
     w.document.getElementsByTagName("HEAD")[0].appendChild(s); 

     var s2 = w.document.createElement("script"); 
     s2.type = "text/javascript"; 
     s2.src = "test2.js"; 
     w.document.getElementsByTagName("HEAD")[0].appendChild(s2); 
    </script> 
</head> 
<body> 
</body> 
</html> 

Nota: lo que hay que tener en cuenta con esta solución es que los archivos javascript ahora se cargan de forma asíncrona, por lo que si usted tiene dependencias entre los archivos, no se puede estar seguro que cargarán en el orden correcto. Lo solucioné con setTimeout y probando la existencia de variables en el primer archivo antes de cargar el segundo archivo.

+1

El problema real es que cuando la página se carga con 'document.write', IE siempre cargar bloques de JavaScript en línea antes de JavaScript externo archivos, independientemente de cuál se defina primero. Esto se describe en http://www.dynamicdrive.com/forums/blog.php?bt=173 (sección II). Una buena solución es poner todo como archivos javascript externos. – sayap

Respuesta

6

Pruebe algo como esto (no probado):

var s=document.createElement('script'); 
s.type = "text/javascript"; 
s.src = "test.js"; 
document.body.appendChild(s); 
+0

Lo modifiqué un poco: var s = w.document.createElement ("script"); s.type = "text/javascript"; s.src = "test.js"; w.document.getElementsByTagName ("HEAD") [0] .appendChild (s); Y parece funcionar correctamente en IE8 en Windows 7 (y en otros navegadores). Todavía creo que IE tiene un error que dice que mi código original no funciona, pero esto debería funcionar como una solución alternativa. –

1

Es posible que desee considerar la posibilidad de embalar sus llamadas de alerta en la definición de funciones en los archivos js importados, y luego añadir una onLoad de la etiqueta del cuerpo de windowHTML que llama a la función

EDIT:

<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN' 'http://www.w3.org/TR/html4/loose.dtd'> 
<html> 
<head> 
    <script type="text/javascript"> 
     var w = window.open(); 
     w.document.writeln("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">"); 
     w.document.writeln("<html>"); 
     w.document.writeln("<head>"); 
     w.document.writeln("<script type=\"text/javascript\" src=\"test.js\"></scr"+"ipt>"); 
     w.document.writeln("<script type=\"text/javascript\" src=\"test2.js\"></scr"+"ipt>"); 
     w.document.writeln("</head>"); 
     w.document.writeln("<body onload=\"test();test2()\">"); 
     w.document.writeln("</body>"); 
     w.document.writeln("</html>"); 
     w.document.close(); 
    </script> 
</head> 
<body> 
</body> 
</html> 
+0

Intenté su sugerencia para ver si funciona, pero recibo un error de IE que dice "Objeto esperado" cuando llamo a las funciones en la carga. De nuevo, si intento por segunda vez (cuando los archivos javascript ya están en el caché), funciona bien. IE simplemente no los carga correctamente la primera vez. (Mi código real es usar jquery's $ (document) .ready() en los archivos javascript incluidos, no simples alertas. Solo quería quitarlo al caso de prueba más simple que muestra el comportamiento.) –

+0

Si elimina w .document.close(); ¿Cambia el comportamiento en absoluto? Me pregunto si está cerrando la ventana antes de que los scripts tengan la oportunidad de cargarse y ejecutarse por primera vez. –

+0

Si elimino w.document.close(), la página nunca muestra las alertas, incluso en cargas de página posteriores. Entonces intenté poner w.document.close() en un setTimeout, para dar a los scripts mucho tiempo para cargar, pero eso no hizo ninguna diferencia. Entonces, no creo que ese sea el problema. –

-1

No estoy seguro de cuál es su propósito de llamar a una ventana emergente ... si no es esencial tener una ventana separada, puede tratar de tener una capa superpuesta en la página existente en su lugar ... algunas personas lo llaman una caja de luz.

La función window.open en algunos navegadores inicialmente indicará al usuario que "acepte ventanas emergentes" (que sí me molesta), si no necesita una ventana emergente y puede implementar todo en la misma página, puede usar la función jQuery .load en su lugar para cargar el contenido en un contenedor (sin volver a cargar la página).

http://api.jquery.com/load/

+0

Bueno, es un caso muy específico. La nueva ventana contiene dos marcos, uno de los cuales cargo la página actual, y el otro tiene algunos controles que utilizo para interactuar con esa página. No encajaría muy bien en una caja de luz, ya que el objetivo no es ser un cuadro de diálogo. Gracias por la sugerencia, sin embargo. –

Cuestiones relacionadas