Mi página html crea una secuencia de comandos dinámica, donde quiero llamar a una función definida en la secuencia de comandos después de que se carga la página. Estoy configurando manualmente async=false en el script dinámico, pero aún se carga después del DOM, lo que provoca un error cuando intento llamar a la función que aún no está definida. ¿Alguien puede decirme cómo forzar la carga del script dinámico antes del evento DOMContentLoaded? De acuerdo con toda la documentación que puedo encontrar, todos los scripts deben cargarse antes del evento DOMContentLoaded, a menos que async=true. Estoy viendo este comportamiento en Firefox y Chrome. Gracias.
Orden esperado de alertas:
Las alertas de pedido en realidad se están activando:
HtmlPágina1.html:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title></title> </head> <body> <!--<script defer src="JavaScript.js" onload="alert('script loaded');" type="text/javascript"></script>--> <script type="text/javascript"> (function (n, t, a, e, co) { var r = t.createElement("script"); // dynamic scripts are async by default. Must change to ensure script loads before dom loaded. r.async = false; //r.defer = true; r.onload = function () { alert("script loaded"); }; r.src = a; var c = t.getElementsByTagName("script")[0]; c.parentNode.insertBefore(r, c); })(window, document, "JavaScript.js"); // have to delay calling TestFunction until after DOM loaded, because script needs to be loaded first document.addEventListener('DOMContentLoaded', (event) => { alert("dom load"); TestFunction(); }); </script> <div>Test Html Page</div> </body> </html>
JavaScript.js:
function TestFunction() { alert("TestFunction called"); }Cuando agrega una etiqueta de secuencia de comandos a una página con js, tendrá una prioridad baja y se cargará con un retraso en comparación con otras secuencias de comandos de alta prioridad, defer y async no cambiarán nada, el proceso de carga comenzará después de DOMContentLoaded evento, porque DOMContentLoaded no tiene en cuenta los scripts agregados dinámicamente, solo rastrea la carga del html inicial enviado por el servidor.
Lo que significa que una secuencia de comandos diferida puede cargarse antes que una secuencia de comandos no diferida debido a la prioridad, si la secuencia de comandos diferida se carga con prioridad alta y la secuencia de comandos no diferida se carga con prioridad baja.
Deberá escuchar el evento de carga en la etiqueta de secuencia de comandos que agregó si desea hacerlo.
(function (n, t, a, e, co) { var r = t.createElement("script"); // define an id r.id = 'myScript'; r.onload = function () { alert("script loaded"); }; r.src = a; var c = t.getElementsByTagName("script")[0]; c.parentNode.insertBefore(r, c); })(window, document, "JavaScript.js"); // listen to the load event of the actual script tag you added myScript.addEventListener('load', (event) => { alert("dom load"); TestFunction(); });Si no desea hacer eso, deberá reemplazar su js con una etiqueta de secuencia de comandos real en el html:
<script src="JavaScript.js" onload="alert('script loaded');" type="text/javascript"></script> <script type="text/javascript"> document.addEventListener('DOMContentLoaded', (event) => { alert("dom load"); TestFunction(); }); </script>ahora ambas secuencias de comandos se tratarán como secuencias de comandos de alta prioridad porque están en el dom inicial, y la escucha de DOMContentLoaded funcionará
Aquí hay una captura de pantalla de la pestaña de red, con un script dinámico frente a uno estático: