Curso de JavaScript | 14. Fuente de error: acceder a elementos que aún no existe

Iniciado por Abarhild, Septiembre 12, 2022, 02:46:45 PM

Tema anterior - Siguiente tema

gonzabnkr y 1 Visitante están viendo este tema.

No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

Fuente de error: JavaScript intenta acceder a elementos que aún no existen
En el último capítulo vimos que el siguiente programa de JavaScript se canceló con el mensaje de error "Uncaught TypeError: Connot read property ...".

Código: html4strict

<html>
<head>
<title>Titulo de la pagina</title>
</head>
<script>
let parrafo1 = document.getElementById('area1');
document.write("<br>" + parrafo1.innerHTML);
console.log("<br>" + parrafo1);
</script>
<body>
    <h1>Encabezado 1</h1>
    <p id="area1">Primer parrafo con texto</p>
    <p>Segundo parrafo con texto</p>
    <a href="https://foro.elhacker.net">Texto del link</a>
</script>
</body>
</html>


¿Por qué esto es así? Nuestro programa JavaScript intenta a través de document.getElementById('area1'); acceder a un área en HTML que aún no se "muestra" en ese momento. ¿Que se quiere decir con eso? Nuestro párrafo con la ID area1 recién se "ejecuta" más adelante en el programa y solo entonces estara disponible para JavaScript.


La prueba para una mejor comprensión
También podemos hacer que esto sea muy claramente visible al mostrar en la consola lo que actualmente está disponible para JavaScript.

Usando la instrucción console.log(document.children[0].innerHTML); vemos el "estado de carga".

Código: javascript

<html>
<head>
<title>Titulo de la pagina</title>
<script>
console.log(document.children[0].innerHTML);
window.addEventListener("load", function() {
let parrafo1 = document.getElementById('area1');
// console.log(parrafo1.innerHTML);
// console.log(parrafo1);
console.log(document.children[0].innerHTML);
} );
</script>
</head>
<body>
<h1>Encabezado 1</h1>
    <p id="area1">Primer parrafo con texto</p>
    <p>Segundo parrafo con texto</p>
    <a href="https://foro.elhacker.net">Texto del link</a>
<script>
console.log(document.children[0].innerHTML);
</script>
</body>
</html>


La salida de la consola en la línea 6 muestra que solo está presente la sección head; por otro lado, obtenemos el código completo a través del mismo comando en la salida de la consola.


Independiente de la ubicación de nuestro código JavaScript
Y aquí es exactamente donde queremos independizarnos.

Queremos decirle a nuestro programa JavaScript que no se ejecute hasta que se hayan cargado todos los elementos HTML de la página.


EventListener - esperar a eventos definidos usando JavaScript
En JavaScript existen EventListeners que podemos usar para eventos como un clic del usuario, pulsaciones de teclas o incluso la carga completa de todos los elementos HTML en una página. Así que podemos consultar cualquier cantidad de Events (inglés para evento), es decir, esperar y "escuchar" (Listen en inglés) si estos llegan a ocurrir. La traducción al español de EventListener es realmente agradable: es el oidor de eventos.

Veamos la estructura en JavaScript:

La declaración de JavaScript comienza con window.addEventListener(). Después de iniciar nuestro programa JavaScript, a nuestra ventana se monitorea constantemente para ver si ocurre un evento específico. Y aquí el énfasis está en permanente. Compara esto con lenguajes de programación como PHP, donde se ejecuta un programa y cuando este programa ha llegado a la última línea de código, este se completa y termina. Si usamos EventListener en JavaScript, el código asociado se ejecutará en una función tan pronto como ocurra un evento (Event) específico. No te tropiezcas con la nueva palabra de función aquí: las funciones se introduciran más adelante.

Ahora, por supuesto, aún tenemos que decirle a addEventListener() qué evento (Event) debe escuchar:

Código: javascript

window.addEventListener("load" );


Por lo tanto, estamos esperando que nuestro archivo se cargue por completo; en otras palabras, todas las instrucciones HTML están disponibles y JavaScript puede consultarlas o usarlas. Nuestro evento "load" no significa nada más que nuestra página completa ha terminado de cargarse.

Ahora está claro cuándo nuestro EventListener debería de activarse - ahora falta la actividad. Primero echemos un vistazo a la estructura básica:

Código: javascript

window.addEventListener("load", function() {
} );


Y con acción, se debe de mostrarse que la página se cargó por completo:

Código: javascript

window.addEventListener("load", function() {
    console.log("Pagina completamente cargada");
} );


En lugar de nuestra salida de control, por supuesto, se puede colocar cualquier cantidad de declaraciones de JavaScript entre las llaves.

Pero ahora el gran final: por razones históricas (suena siempre bien, pero se refiere a evitar problemas con los navegadores antiguos), siempre se debe de ingresar false después de las llaves.

Código: javascript

window.addEventListener("load", function() {
}, false );


Y ahora podemos insertar el ejemplo inicialmente problemático a la nueva sección y todo está bien:

Código: javascript

<html>
<head>
<title>Titulo de la pagina</title>
</head>
<script>
window.addEventListener("load", function() {
    let parrafo1 = document.getElementById('area1');
    console.log(parrafo1.innerHTML);
    console.log(parrafo1);
}, false );
</script>
<body>
    <h1>Encabezado 1</h1>
    <p id="area1">Primer parrafo con texto</p>
    <p>Segundo parrafo con texto</p>
    <a href="https://foro.elhacker.net">Texto del link</a>
</body>
</html>


En los siguientes tutoriales siempre trabajaré con esta construcción para evitar estos problemas. Por lo tanto, utilícenlo siempre, incluso si addEventListener("load", ...) no se muestra en los ejemplos que vienen en aras de la claridad.