2008-09-18 15 views
36

He la secuencia de comandos siguiente, donde el primer y tercer document.writeline son estáticos y la segunda se genera:document.write Inline Guión orden de ejecución de JavaScript

<script language="javascript" type="text/javascript"> 
document.write("<script language='javascript' type='text/javascript' src='before.js'><\/sc" + "ript>"); 
document.write("<script language='javascript' type='text/javascript'>alert('during');<\/sc" + "ript>"); 
document.write("<script language='javascript' type='text/javascript' src='after.js'><\/sc" + "ript>"); 
</script> 

Firefox y Chrome mostrará antes, durante y después , mientras que Internet Explorer primeros espectáculos durante y sólo entonces se muestran antes y después de.

Me he encontrado con an article that states que no soy el primero en encontrar esto, pero eso apenas me hace sentir mejor.

¿Alguien sabe cómo puedo configurar el orden para que sea determinista en todos los navegadores, o hackear IE para que funcione como todos los demás, lo hacen los navegadores seguros?

Advertencias: El fragmento de código es una reproducción muy simple. Se genera en el servidor y el segundo script es lo único que cambia. Es un guión largo y la razón por la que hay dos guiones antes y después es para que el navegador los guarde en caché y la parte dinámica del código sea lo más pequeña posible. También puede aparecer muchas veces en la misma página con diferentes códigos generados.

+0

deben leer: http://html5rocks.com/en/tutorials/speed/script-loading – Pacerier

Respuesta

5

he encontrado una respuesta más a mi gusto:

<script language="javascript" type="text/javascript"> 
document.write("<script language='javascript' type='text/javascript' src='before.js'><\/sc" + "ript>"); 
document.write("<script defer language='javascript' type='text/javascript'>alert('during');<\/sc" + "ript>"); 
document.write("<script defer language='javascript' type='text/javascript' src='after.js'><\/sc" + "ript>"); 
</script> 

Esto le diferir la carga de ambos durante y después de hasta que la página ha terminado de cargar.

Creo que esto es lo mejor que puedo conseguir. Con suerte, alguien podrá dar una mejor respuesta.

+6

Internet Explorer ejecuta scripts en línea antes de scripts externos. Para obtener un orden coherente, mueva el código en línea a un archivo externo. –

1

Diapositivas 25/26 de this presentation hablan sobre las características de los diferentes métodos para insertar scripts. Sugiere que IE es el único navegador que ejecutará esos scripts en orden. Todos los demás navegadores los ejecutarán en el orden en que terminen de cargarse. Incluso IE no los ejecutará en orden si uno o más tienen js en línea en lugar de src.

Uno de los métodos sugeridos es insertar un nuevo elemento DOM:

var se1 = document.createElement('script'); 
se1.src = 'a.js'; 

var se2 = document.createElement('script'); 
se2.src = 'b.js'; 

var se3 = document.createElement('script'); 
se3.src = 'c.js'; 

var head = document.getElementsByTagName('head')[0] 
head.appendChild(se1); 
head.appendChild(se2); 
head.appendChild(se3); 

para hacer la segunda sección de script generado se puede utilizar una secuencia de comandos para generar ese contenido y pasar los parámetros:

se2.src = 'generateScript.php?params=' + someParam; 

EDITAR: a pesar de lo que dice el artículo que situé, mi prueba sugiere que la mayoría de los navegadores ejecutarán tus guiones document.write en orden si cada uno tiene un src, así que aunque creo que el método anterior es preferible, podrías hacer esto también:

<script language="javascript" type="text/javascript"> 
document.write("<script type='text/javascript' src='before.js'><\/sc" + "ript>"); 
document.write("<script type='text/javascript' src='during.php?params=" + params + "'><\/sc" + "ript>"); 
document.write("<script type='text/javascript' src='after.js'><\/sc" + "ript>"); 
</script> 

EDITAR DE NUEVO (respuesta a los comentarios a mí y a los demás): Ya está generando el script en su página. Lo que sea que esté haciendo se puede mover a otra secuencia de comandos del lado del servidor que genera el mismo bloque de código. Si necesita parámetros en su página, páselos a la secuencia de comandos en la cadena de consulta.

Además, se puede usar este mismo método si, como usted sugiere, que están generando las secuencias de comandos en línea varias veces:

<script language="javascript" type="text/javascript"> 
document.write("<script type='text/javascript' src='before.js'><\/sc" + "ript>"); 
document.write("<script type='text/javascript' src='during.php?params=" + params1 + "'><\/sc" + "ript>"); 
document.write("<script type='text/javascript' src='during.php?params=" + params2 + "'><\/sc" + "ript>"); 
document.write("<script type='text/javascript' src='during.php?params=" + params3 + "'><\/sc" + "ript>"); 
document.write("<script type='text/javascript' src='after.js'><\/sc" + "ript>"); 
</script> 

Sin embargo, esto está empezando a parecer que se está acercando a mal . Si está generando un bloque grande de código varias veces, probablemente debería reemplazarlo con una única función js y llamarlo con diferentes params en su lugar ...

+0

'durante' es una pieza muy larga de la escritura, por lo que puedo' t lo resume en una simple solicitud de obtención ... –

+0

@Omer: Ya lo ha resumido en una "solicitud de obtención simple" ... ¿Cómo lo está generando ahora para ponerlo en línea? Lo que sea que estés haciendo ahora, podrías hacerlo en otra página, pero solo devuelve el js y no el resto de la página. – Prestaul

+0

el código de demostración que di es una reproducción muy simplificada del problema. el código que escribí es el que se genera y el archivo incluye para que el navegador los guarde en caché y necesite menos tiempo para cargar la página. –

1

Bien ... durante ...

// During.js 
during[fish](); 

después ...

// After.js 
alert("After"); 
fish++ 

HTML

<!-- some html --> 
<script language="javascript" type="text/javascript"> 
document.write("<script language='javascript' type='text/javascript' src='before.js'></sc" + "ript>"); 
document.write("<script language='javascript' type='text/javascript'>during[" + fish + "] = function(){alert('During!' + fish);}</sc" + "ript>"); 
document.write("<script language='javascript' type='text/javascript' src='during.js'></sc" + "ript>"); 
document.write("<script language='javascript' type='text/javascript' src='after.js'></sc" + "ript>"); 
</script> 
<!-- some other html --> 
<script language="javascript" type="text/javascript"> 
document.write("<script language='javascript' type='text/javascript' src='before.js'></sc" + "ript>"); 
document.write("<script language='javascript' type='text/javascript'>during[" + fish + "] = function(){alert('During!' + fish);}</sc" + "ript>"); 
document.write("<script language='javascript' type='text/javascript' src='during.js'></sc" + "ript>"); 
document.write("<script language='javascript' type='text/javascript' src='after.js'></sc" + "ript>"); 
</script> 

me inclino a estar de acuerdo acerca de la forma en que esto está empezando a oler, sin embargo. En particular, ¿por qué no podría codegen el "durante" en un archivo js creado dinámicamente e insertar eso?

Tenga en cuenta que el script generado dinámicamente va dentro la función en el segundo document.write.
Probado en FF2, IE7

24

No, este es el comportamiento de Internet Explorer.

Si adjunta scripts dinámicamente, IE, Firefox y Chrome descargarán los scripts de forma asíncrona.

Firefox y Chrome esperarán hasta que todas las solicitudes asincrónicas regresen y luego ejecutarán las secuencias de comandos en el orden en que se adjuntan en el DOM pero IE ejecuta las secuencias de comandos en el orden en que se devuelven por cable.

Dado que la alerta toma menos tiempo para "recuperar" que un archivo javascript externo, eso probablemente explica el comportamiento que está viendo.

De Kristoffer Henriksson de post on the subject of asynchronous script loading:

En este escenario IE y Firefox se descarga ambas secuencias de comandos, pero Internet Explorer también ejecutarlos en el orden que terminen de descargar en mientras que Firefox se descarga a de forma asíncrona, pero todavía los ejecuta en el orden en que se adjuntan en el DOM.

En Internet Explorer Esto significa que su scripts no pueden tener dependencias en unos a otros como la orden de ejecución variará dependiendo del tráfico de red , cachés, etc.

considerar el uso de un cargador de Javascript. Le permitirá especificar las dependencias del script y el orden de ejecución mientras también carga los scripts de forma asíncrona para la velocidad y suaviza algunas de las diferencias del navegador.

Esta es una muy buena descripción de algunos de ellos: Essential JavaScript: the top five script loaders.

He usado tanto RequireJS como LabJS. En mi opinión, LabJS es un poco menos obstinado.

0

código para proporcionar:

<script language="javascript" type="text/javascript"> 
document.write("<script language='javascript' type='text/javascript'>function callGeneratedContent() { alert('during'); }<\x2Fscript>"); 
document.write("<script language='javascript' type='text/javascript' src='before.js'><\x2Fscript>"); 
document.write("<script language='javascript' type='text/javascript' src='after.js'><\x2Fscript>"); 
</script> 

En before.js:

alert("Before"); 
callGeneratedContent(); 

En después.JS:

alert("After"); 

usted tiene que poner primero la línea generada, de lo contrario FF se quejará porque ejecuta before.js antes de ver la definición de la función.

+0

por favor vea la advertencia a la respuesta de Dustman. –

1

Puede forzar la ejecución secuencial definiendo eventos "onload" (o similares) en los scripts e inyecte el siguiente en la función de evento. No es trivial, pero hay muchos ejemplos, aquí hay uno.

http://www.phpied.com/javascript-include-ready-onload/

creo bibliotecas populares como jQuery o prototipo puede ayudar con esto.

0

¿Qué tal que:

<script> 
document.write("<script src='before.js'><\/script>"); 
</script> 

<script > 
document.write("<script>alert('during');<\/script>"); 
</script> 

<script> 
document.write("<script src='after.js'><\/script>"); 
</script> 
Cuestiones relacionadas