javascript - pagina - ha fallado la carga del<script> con origen
Los scripts asÃncronos cargados con DOMContentLoaded o los gestores de eventos de carga no se llaman? (4)
Al cargar el script de forma asíncrona, le está diciendo al navegador que puede cargar ese script independientemente de las otras partes de la página. Eso significa que la página puede terminar de cargarse y puede disparar DOMContentLoaded
ANTES de que se DOMContentLoaded
su script y antes de que se registre para el evento. Si eso sucede, perderá el evento (ya sucedió cuando se registró).
En algunos navegadores, puede probar el documento para ver si ya está cargado. No he comprobado toda la compatibilidad del navegador, pero en Firefox 3.6 o superior ( documento MDN ), puede verificar:
if (document.readyState !== "loading")
para ver si el documento ya está cargado. Si es así, solo haz tu negocio. Si no es así, entonces instale su detector de eventos.
De hecho, como fuente de referencia e idea de implementación, jQuery hace lo mismo con su método .ready()
y parece ampliamente soportado. jQuery tiene este código cuando se llama a .ready()
que primero verifica si el documento ya está cargado. Si es así, llama a la función Ready inmediatamente en lugar de vincular al detector de eventos:
// Catch cases where $(document).ready() is called after the
// browser event has already occurred.
if ( document.readyState === "complete" ) {
// Handle it asynchronously to allow scripts the opportunity to delay ready
return setTimeout( jQuery.ready, 1 );
}
Tengo un script con un DOMContentLoaded
eventos DOMContentLoaded:
document.addEventListener(''DOMContentLoaded'', function() {
console.log(''Hi'');
});
Que estoy cargando de forma asíncrona:
<script async src=script.js></script>
Sin embargo, el controlador de eventos nunca se llama . Si lo cargo sincrónicamente
<script src=script.js></script>
Funciona bien.
(Incluso si cambio el evento DOMContentLoaded
a un evento de load
, nunca se llama).
¿Lo que da? El controlador de eventos se debe registrar independientemente de cómo el script carga el script, ¿no?
Edición : no funciona en Chrome 18.0.1025.11 beta pero, con DOMContentLoaded
, funciona en Firefox 11 beta (pero con load
no). Imagínate.
¡OH GRANDES SEÑORES DE JAVASCRIPT Y EL DOM, OREMOSTE EL ERROR DE MIS MANERAS!
Esta no es la respuesta final, pero me hizo entender por qué no es correcto usar async con un script que necesita modificar DOM, por lo que debe esperar al evento DOMContentLoaded. La esperanza podría ser beneficiosa.
(Fuente: Ejecución de su código en el momento adecuado desde kirupa.com )
Una forma de evitar esto es usar el evento load en el objeto de ventana.
Esto sucederá más tarde que DOMContentLoaded, pero al menos no tiene que preocuparse por perder el evento.
window.addEventListener("load", function () {
console.log(''window loaded'');
});
Si realmente necesita capturar el evento DOMContentLoaded, puede usar el objeto Promise. La promesa se resolverá incluso si sucedió antes:
HTMLDocument.prototype.ready = new Promise(function (resolve) {
if (document.readyState != "loading")
return resolve();
else
document.addEventListener("DOMContentLoaded", function () {
return resolve();
});
});
document.ready.then(function () {
console.log("document ready");
});
Simulando una conexión 3G lenta con los controles de Chrome tuve problemas al manipular el DOM desde un script async
externo, sin embargo, este fragmento de código que encontré en algún lugar de GitHub lo resolvió por mí:
var DOMReady = function(callback) {document.readyState === "interactive" || document.readyState === "complete" ? callback() : document.addEventListener("DOMContentLoaded", callback);};
DOMReady(function() {
//DOM is ready!
});
¿Alguien puede responder por esto?
¿Cómo se compara esto con las soluciones ya sugeridas?
https://javascript.info/onload-ondomcontentloaded#readystate