Estoy tratando de comprender mejor la relación entre cómo JavaScript actualiza el objeto DOM. Aquí está mi archivo html index.html :
<!DOCTYPE html> <html lang="en"> <head> </head> <body> <div id="container">old</div> </body> <script src="script.js"></script> </html> y aquí está mi archivo JavaScript script.js ,
const container = document.getElementById("container"); console.log(container, container.innerHTML); container.innerHTML = "new"; console.log(container, container.innerHTML); La consola registra la misma etiqueta <div> pero con un HTML innerHTML diferente, lo cual es bastante inesperado:
<div id="container">new</div> 'old' <div id="container">new</div> 'new' Por lo tanto, mi primera pregunta es, ¿qué hace posible que la consola imprima los mismos elementos div pero un innerHTML diferente?
En segundo lugar, hice un pequeño cambio en mi script con setTimeout ,
let timeout = 30; setTimeout(() => { container.innerHTML = "new"; console.log(container, container.innerHTML); }, timeout); Aunque container.innerHTML siempre se imprime con un valor diferente, como se esperaba, descubrí que si el valor de tiempo de espera está por encima de 35. Es casi seguro que la etiqueta div se imprime de manera diferente con,
<div id="container">old</div> 'old' <div id="container">new</div> 'new' Entonces sucede algo que no entiendo. Cuando el tiempo de timeout se establece por debajo de 10, es casi seguro que la etiqueta div se imprime como,
<div id="container">new</div> 'old' <div id="container">new</div> 'new' Cuando el tiempo de timeout se establece en algún lugar entre 10 y 30, el resultado cambia, lo que significa que a veces
<div id="container">new</div> 'old' <div id="container">new</div> 'new'y aveces
<div id="container">old</div> 'old' <div id="container">new</div> 'new'Por lo tanto, mi segunda pregunta es, ¿qué causa esta diferencia?
Muy apreciado.
Con suerte, puedo responder a ambas preguntas con esto:
Tenga en cuenta que la propiedad innerHTML es sincrónica , lo que significa que la siguiente línea no debe ejecutarse hasta que finalice el proceso. Sin embargo, el DOM real debe renderizarse nuevamente, y esto sucede por separado (o de forma asíncrona ). La representación visual en el DOM no sucede hasta que se completa la pila de funciones en JavaScript. Por lo tanto, sus comandos console.log() están recuperando información antes de que el DOM se haya procesado con el nuevo código HTML.
Estás viendo esto con lo que has mostrado en tu segunda pregunta. Cuando usa un setTimeout() entre 10 y 30 ms, a veces el DOM se procesa nuevamente lo suficientemente rápido como para que su console.log() se ejecute ahora en el innerHTML actualizado. Por supuesto, la ejecución de programas y funciones a lo largo de la programación nunca se completa exactamente en el mismo momento por todo tipo de razones.
Este hilo puede ayudarte a entender.