Quiero ejecutar un poco de javascript antes de que se cargue toda la página. es posible? ¿O el código comienza a ejecutarse </html>
?
javascript
html
picknick
fuente
fuente
Respuestas:
No sólo puede usted, pero usted tiene que hacer un esfuerzo especial no a si no quieren. :-)
Cuando el navegador encuentra una
script
etiqueta clásica al analizar el HTML, deja de analizar y se lo entrega al intérprete de JavaScript, que ejecuta el script. El analizador no continúa hasta que se completa la ejecución del script (porque el script puede hacerdocument.write
llamadas al marcado de salida que el analizador debería manejar).Ese es el comportamiento predeterminado, pero tiene algunas opciones para retrasar la ejecución del script:
Utilice módulos de JavaScript. Un
type="module"
script se aplaza hasta que el HTML se haya analizado por completo y se haya creado el DOM inicial. Esta no es la razón principal para usar módulos, pero es una de las razones:El código se obtendrá (si está separado) y se analizará en paralelo con el análisis de HTML, pero no se ejecutará hasta que finalice el análisis de HTML. (Si el código de su módulo está en línea en lugar de en su propio archivo, también se aplaza hasta que se complete el análisis de HTML).
Esto no estaba disponible cuando escribí esta respuesta por primera vez en 2010, pero aquí en 2020, todos los principales navegadores modernos admiten módulos de forma nativa, y si necesita admitir navegadores más antiguos, puede usar paquetes como Webpack y Rollup.js.
Utilice el
defer
atributo en una etiqueta de secuencia de comandos clásica:Al igual que con el módulo, el código en se
my-code.js
buscará y analizará en paralelo con el análisis de HTML, pero no se ejecutará hasta que finalice el análisis de HTML. Sin embargo ,defer
no funciona con el contenido de la escritura en línea, sólo con archivos externos referenciados a travéssrc
.No creo que sea lo que desea, pero puede usar el
async
atributo para decirle al navegador que busque el código JavaScript en paralelo con el análisis de HTML, pero luego ejecútelo lo antes posible, incluso si el análisis de HTML no está completo. . Puede ponerlo en unatype="module"
etiqueta o usarlo en lugar dedefer
unascript
etiqueta clásica .Coloque la
script
etiqueta al final del documento, justo antes de la</body>
etiqueta de cierre :De esa manera, aunque el código se ejecute tan pronto como se encuentre, todos los elementos definidos por el HTML anterior existen y están listos para ser utilizados.
Solía ser que esto causaba un retraso adicional en algunos navegadores porque no comenzarían a buscar el código hasta que
script
se encontrara la etiqueta, pero los navegadores modernos escanean con anticipación y comienzan a buscar previamente. Aún así, esta es la tercera opción en este punto, ambos módulosdefer
son mejores opciones.La especificación tiene un diagrama útil que muestra un
script
etiqueta,defer
,async
,type="module"
, ytype="module" async
y el momento de cuando el código JavaScript se capta y ejecute:A continuación, se muestra un ejemplo del comportamiento predeterminado, una
script
etiqueta sin formato:(Vea mi respuesta aquí para obtener detalles sobre ese
NodeList
código).Cuando ejecutas eso, ves "Párrafo 1" en verde pero "Párrafo 2" es negro, porque el script se ejecutó sincrónicamente con el análisis HTML, por lo que solo encontró el primer párrafo, no el segundo.
En contraste, aquí hay un
type="module"
guión:Observe cómo ambos están verdes ahora; el código no se ejecutó hasta que se completó el análisis de HTML. Eso también sería cierto con un
defer
script
contenido externo (pero no contenido en línea).(No era necesario realizar la
NodeList
comprobación allí porque cualquier módulo de soporte de navegador moderno ya tieneforEach
activadoNodeList
).En este mundo moderno, no hay valor real para el
DOMContentLoaded
evento de la función "listo" que PrototypeJS, jQuery, ExtJS, Dojo y la mayoría de los demás proporcionaron en el pasado (y aún brindan); simplemente use módulos odefer
. Incluso en el pasado, no había muchas razones para usarlos (y a menudo se usaban incorrectamente, reteniendo la presentación de la página mientras se cargaba toda la biblioteca jQuery porquescript
estaba enhead
el documento en lugar de después), algo que algunos desarrolladores en Google marcó desde el principio. Esto también fue parte del motivo de la recomendación de YUI de poner guiones al final delbody
, nuevamente en el pasado.fuente
<body onload="doIt()>"
.load
evento ocurre muy tarde en el ciclo de carga de la página, casi nunca es una buena práctica esperar para ejecutar JavaScript hasta entonces. Pero sí, es una opción. Por cierto, revisé la respuesta para 2020.document.addEventListener('DOMContentLoaded', function(){ //doyour stuff })
Puede ejecutar código JavaScript en cualquier momento. AFAIK, se ejecuta en el momento en que el navegador llega a la etiqueta <script> donde se encuentra. Pero no se puede acceder a los elementos que aún no están cargados.
Entonces, si necesita acceder a los elementos, debe esperar hasta que se cargue el DOM (esto no significa que se cargue toda la página, incluidas las imágenes y demás. Es solo la estructura del documento, que se carga mucho antes, por lo que generalmente gana no noto un retraso), usando el
DOMContentLoaded
evento o funciones como$.ready
en jQuery.fuente