type script para pagina llamar insertar incluir funcion evento etiqueta ejemplos ejecutar documentos desde cómo cargar carga asincrona antes javascript scripting dynamic load labjs

javascript - para - script html ejemplos



¿Se puede confiar en script.readyState para detectar el final de la carga del script dinámico? (5)

Uso la carga dinámica de scripts para reducir la duración de la carga de la página inicial. Para garantizar que las funciones y objetos definidos por un script sean accesibles, necesito asegurarme de que el script se haya cargado por completo.

He desarrollado mi propia biblioteca de Javascript para este fin, y así investigué bastante sobre el tema, estudiando cómo se hace en diferentes bibliotecas. Durante una discusión relacionada con este tema, Kyle Simpson, el autor de LABjs , declaró que:

LABjs (y muchos otros cargadores) configuran tanto "onload" como "onreadystatechange" en todos los elementos del script, sabiendo que algunos navegadores dispararán uno, y algunos dispararán el otro ...

Puede encontrar un ejemplo de esto en la versión actual de jQuery a partir de este escrito, v1.3.2 :

// Attach handlers for all browsers script.onload = script.onreadystatechange = function(){ if ( !done && (!this.readyState || this.readyState == "loaded" || this.readyState == "complete") ) { done = true; success(); complete(); // Handle memory leak in IE script.onload = script.onreadystatechange = null; head.removeChild( script ); } };

Ese es el estado de la técnica, pero durante el análisis de un comportamiento extraño en Opera 9.64, llegué a la conclusión de que, utilizando esta técnica, la devolución de llamada de carga se activó demasiado pronto.

Publicaré mis propios hallazgos en respuesta a esta pregunta, y me gustaría recabar más evidencia y comentarios de la comunidad.


Descubrí que Internet Explorer (prueba en 9) NO SIEMPRE tiene su script listo cuando readyState === ''loaded''. He tenido éxito usando este controlador de eventos (en 9 por supuesto) onactivate . Estaba jalando mi pelo antes.


En Firefox, Safari y Chrome, se llama al controlador onreadystatechange nevers.

Creé un caso de prueba breve, creando un script dinámico con solo el conjunto de controladores onreadystatechange:

<script type="text/javascript" language="javascript"> bezen.log.info(new Date(),true); bezen.log.info(navigator.userAgent,true); // Activate logs bezen.log.on(); bezen.log.info(''Test for script.readyState behavior started''); var script = document.createElement(''script''); script.src = ''test1.js''; script.onreadystatechange = function(){ bezen.log.info(''readystatechange: ''+script.readyState); }; document.body.appendChild(script); bezen.log.info(''Added script with onreadystatechange handler''); </script>

Realicé la prueba en un archivo local en Firefox 2, Firefox 3, Firefox 3.5, Safari 3, Safari 4 y Chrome 3, y obtuve resultados similares (aquí los registros registrados en FF 3.5):

Fri Dec 18 2009 17:53:58 GMT+0100 Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6 Test for script.readyState behavior started Added script with onreadystatechange handler test1.js: Start test1.js: Start of closure test1.js: End of closure

El cambio de estado continuo nunca se llama. En estos navegadores, solo el escucha de onload es útil para detectar el final de la carga de un script, el onreadystatechange no es necesario.


En Internet Explorer, el controlador onreadystatechange se desencadena como se esperaba después del final del script.

Realicé la misma prueba en Internet Explorer 6, Internet Explorer 7 e Internet Explorer 8, con resultados similares en estos tres navegadores (aquí los registros registrados en Internet Explorer 6):

Fri Dec 18 18:14:51 UTC+0100 2009 Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729) Test for script.readyState behavior started Added script with onreadystatechange handler test1.js: Start test1.js: Start of closure test1.js: End of closure readystatechange: complete

Aquí, con una prueba que usa un archivo local, el readyState siempre está "completo", y seguía siendo el mismo después de varias páginas de actualización.

Sin embargo, como se señala en esta publicación de Nicholas C. Zakas , también puede observar "cargado" y "completo", o simplemente "cargado", bajo diferentes circunstancias.


En Opera, no se puede confiar en la propiedad script.readyState. Por ejemplo, el readyState "cargado" puede activarse antes de que el script se ejecute en Opera 9.64.

Realicé la misma prueba en Opera 9.64 y Opera 10, con diferentes resultados.

En Opera 9.64, el controlador onreadystatechange se activa dos veces, una vez antes y otra vez después de que se ejecuta el script. La propiedad readyState está "cargada" en ambos casos, lo que significa que no se puede confiar en que este valor detecte el final de la carga del script:

# Fri Dec 18 2009 17:54:43 GMT+0100 # Opera/9.64 (Windows NT 5.1; U; en) Presto/2.1.1 Test for script.readyState behavior started Added script with onreadystatechange handler readystatechange: loaded test1.js: Start test1.js: Start of closure test1.js: End of closure readystatechange: loaded

En Opera 10, el controlador onreadystatechange aún se dispara dos veces con el valor "cargado", pero las dos veces después de ejecutar el script:

# Fri Dec 18 2009 18:09:58 GMT+0100 # Opera/9.80 (Windows NT 5.1; U; en) Presto/2.2.15 Version/10.10 Test for script.readyState behavior started Added script with onreadystatechange handler test1.js: Start test1.js: Start of closure test1.js: End of closure readystatechange: loaded readystatechange: loaded

Estos diferentes comportamientos indican que onreadystatechange no es una forma confiable de detectar el final de una carga de script en Opera. Dado que Opera también es compatible con el oyente de carga, este otro mecanismo debería utilizarse en su lugar.

En función de los resultados de estas pruebas, onreadystatechange solo debe utilizarse para detectar el final de la carga del script en Internet Explorer, y no debe configurarse en otros navegadores.


Resultados similares en Chrome.

No toma en curso ...

Solo carga y onerror.