Listado completo de tutoriales

Eventos: load y DOMContentLoaded


Como hemos visto hasta ahora uno de los usos principales de JavaScript es la implementación de algoritmos que reaccionan a eventos que se producen en una página web. Cuando se termina de cargar completamente una página web se dispara el evento onload, cuando se presiona un botón de tipo submit se dispara el evento onsubmit, cuando movemos la flecha del mouse se dispara onmousemove y otra gran cantidad de eventos que nos informa el navegador y nosotros podemos capturarlos y hacer un algoritmo a nuestra medida.

A lo largo de estos más de 25 años de la existencia de JavaScript, se han implementado tres formas distintas de capturar los eventos que emite el navegador.

Eventos definidos directamente en la marca HTML.

Esta metodología esta en desuso, de todos modos muchos sitios antiguos implementan esta técnica.

Problema

Implementar un formulario que solicite la carga del nombre de usuario y su clave. Mostrar un mensaje si no se ingresan datos en alguno de los dos controles.

<!DOCTYPE html>
<html>

<head>
    <title>Ejemplo de JavaScript</title>
    <meta charset="UTF-8">
</head>

<body>

    <form method="post" action="procesar.php" onsubmit="validar();" id="formulario1">
        Ingrese nombre:
        <input type="text" id="usuario" name="usuario" size="20">
        <br> Ingrese clave:
        <input type="password" id="clave" name="clave" size="20">
        <br>
        <input type="submit" id="confirmar" name="confirmar" value="Confirmar">
    </form>

    <script>
        function validar() {
            let usu = document.getElementById("usuario").value;
            let cla = document.getElementById("clave").value;
            if (usu.length == 0 || cla.length == 0) {
                alert('El nombre de usuario o clave está vacío');
                return false;
            } else
                return true;
        }
    </script>

</body>
</html

Lo primero que tenemos que ver que la marca form define la propiedad onsubmit y le asigna el nombre de la función JavaScript que debe llamarse previo a que el navegador empaquete todos los datos del formulario y los envía al servidor para ser procesados:

<form method="post" action="procesar.php" onsubmit="validar();">

Como vemos debemos indicar el nombre de la función y los paréntesis (en este caso no se envían parámetros por lo que los paréntesis van abiertos y cerrados)

En el bloque JavaScript debemos implementar la función validar donde extraemos los valores de cada control y verificamos si alguno de los dos no tiene cargado caracteres, en caso que suceda esto mostramos un mensaje y retornamos un false para que el navegador no envíe los datos del formulario al servidor. Si la función retorna true los datos del formulario son enviados por el navegador al servidor:

        function validar() {
            let usu = document.getElementById("usuario").value;
            let cla = document.getElementById("clave").value;
            if (usu.length == 0 || cla.length == 0) {
                alert('El nombre de usuario o clave está vacío');
                return false;
            } else
                return true;
        }

Esta metodología de inicializar eventos debe ser evitada en todo lo posible.

Eventos definidos accediendo a propiedades del objeto.

Esta metodología es todavía ampliamente utilizada ya que la mayoría de los navegadores lo implementan en forma similar.

Problema

Implementar un formulario que solicite la carga del nombre de usuario y su clave. Mostrar un mensaje si no se ingresan datos en alguno de los dos controles.

<!DOCTYPE html>
<html>

<head>
    <title>Ejemplo de JavaScript</title>
    <meta charset="UTF-8">
</head>

<body>

    <form method="post" action="procesar.php" id="formulario1">
        Ingrese nombre:
        <input type="text" id="usuario" name="usuario" size="20">
        <br> Ingrese clave:
        <input type="password" id="clave" name="clave" size="20">
        <br>
        <input type="submit" id="confirmar" name="confirmar" value="Confirmar">
    </form>

    <script>
        window.onload = inicio;

        function inicio() {
            document.getElementById("formulario1").onsubmit = validar;
        }

        function validar() {
            let usu = document.getElementById("usuario").value;
            let cla = document.getElementById("clave").value;
            if (usu.length == 0 || cla.length == 0) {
                alert('El nombre de usuario o clave está vacío');
                return false;
            } else
                return true;
        }
    </script>

</body>

</html>

Con esta segunda metodología vemos que el código HTML queda limpio de llamadas a funciones JavaScript y todo el código queda dentro del bloque del script (pudiendo luego llevar todo este bloque a un archivo externo *.js)

Lo primero que vemos es inicializar la propiedad onload del objeto window con el nombre de la función que se ejecutará cuando finalice la carga completa de la página, es importante notar que a la propiedad onload le asignamos el nombre de la función y NO debemos disponer los paréntesis abiertos y cerrados (ya que no se está llamando a la función sino le estamos pasando la dirección o referencia de la misma)

        window.onload = inicio;

La función inicio es llamada por el objeto window cuando se termina de cargar la página. En esta función obtenemos la referencia del objeto formulario1 mediante el método getElementById e inicializamos la propiedad onsubmit con el nombre de la función que será llamada cuando se presione el botón submit del formulario:

        function inicio() {
            document.getElementById("formulario1").onsubmit = validar;
        }

Por último tenemos la función validar que verifica si los dos controles del formulario están cargados:

        function validar() {
            let usu = document.getElementById("usuario").value;
            let cla = document.getElementById("clave").value;
            if (usu.length == 0 || cla.length == 0) {
                alert('El nombre de usuario o clave está vacío');
                return false;
            } else
                return true;
        }

La misma metodología pero utilizando funciones anónimas para cada evento el código ahora queda mas conciso:

<!DOCTYPE html>
<html>

<head>
    <title>Ejemplo de JavaScript</title>
    <meta charset="UTF-8">
</head>

<body>

    <form method="post" action="procesar.php" id="formulario1">
        Ingrese nombre:
        <input type="text" id="usuario" name="usuario" size="20">
        <br> Ingrese clave:
        <input type="password" id="clave" name="clave" size="20">
        <br>
        <input type="submit" id="confirmar" name="confirmar" value="Confirmar">
    </form>

    <script>
        window.onload = function() {
            document.getElementById("formulario1").onsubmit = function() {
                let usu = document.getElementById("usuario").value;
                let cla = document.getElementById("clave").value;
                if (usu.length == 0 || cla.length == 0) {
                    alert('El nombre de usuario o clave está vacío');
                    return false;
                } else
                    return true;
            }
        }
    </script>

</body>

</html>

Analicemos un poco el código implementado, a la propiedad onload del objeto window le asignamos una función anónima:

        window.onload = function() {
        ...
        }

En la implementación de la función anónima inicializamos la propiedad onsubmit del objeto formulario1 con otra función anónima:

            document.getElementById("formulario1").onsubmit = function() {
            ...
            }

Esta sintaxis de funciones anónimas es ampliamente utilizado.

Modelo de eventos definidos por W3C (World Wide Web Consortium)

Este modelo de eventos se basa en la implementación de un método para todos los objetos que nos permite registrar eventos. La sintaxis del método es:

  addEventListener(evento, método a ejecutar);

Veamos como implementamos el problema anterior utilizando este nuevo modelo de eventos:

<!DOCTYPE html>
<html>

<head>
    <title>Ejemplo de JavaScript</title>
    <meta charset="UTF-8">
</head>

<body>

    <form method="post" action="procesar.php" id="formulario1">
        Ingrese nombre:
        <input type="text" id="usuario" name="usuario" size="20">
        <br> Ingrese clave:
        <input type="password" id="clave" name="clave" size="20">
        <br>
        <input type="submit" id="confirmar" name="confirmar" value="Confirmar">
    </form>

    <script>
        window.addEventListener('load', inicio);

        function inicio() {
            document.getElementById("formulario1").addEventListener('submit', validar);
        }

        function validar(evt) {
            let usu = document.getElementById("usuario").value;
            let cla = document.getElementById("clave").value;
            if (usu.length == 0 || cla.length == 0) {
                alert('El nombre de usuario o clave está vacío');
                evt.preventDefault();
            }
        }
    </script>

</body>

</html>

Lo primero que vemos es que en vez de inicializar la propiedad onload procedemos a llamar al método addEventListener:

        window.addEventListener('load', inicio);

El primer parámetro es un string con el nombre del evento a inicializar, el segundo parámetro es el nombre de la función a ejecutar .

Cuando se carga completamente la página el objeto window tiene la referencia al método que se debe llamar, en nuestro caso se llama inicio. La función inicio obtiene la referencia del objeto formulario1 y procede a registrar el evento submit indicando en el segundo parámetro el nombre de la función que debe ejecutarse:

        function inicio() {
            document.getElementById("formulario1").addEventListener('submit', validar);
        }

El código de la función validar se modifica, llega como parámetro una referencia al evento y mediante este llamamos al método preventDefault si queremos que no se envíen los datos al servidor:

        function validar(evt) {
            let usu = document.getElementById("usuario").value;
            let cla = document.getElementById("clave").value;
            if (usu.length == 0 || cla.length == 0) {
                alert('El nombre de usuario o clave está vacío');
                evt.preventDefault();
            }
        }

Este modelo de eventos está siendo ampliamente implementado por los navegadores modernos. El problema es el IE8 o inferiores que no lo implementa de esta forma.

Evento DOMContentLoaded

  • Evento 'load': El evento load se dispara cuando el contenido del archivo HTML y las referencias a todos los recursos asociados (imágenes, hojas de estilo etc.) se han cargado en memoria del navegador.
  • Evento 'DOMContentLoaded': El evento DOMContentLoaded se dispara cuando el contenido del archivo HTML se ha cargado en el navegador, sin necesitar esperar imágenes, hojas de estilo etc.
    Es muy conveniente en la mayoría de las veces inicializar script de JavaScript utilizando éste evento en lugar del evento 'load'. Todos los navegadores modernos disponen del evento 'DOMContentLoaded'.

En el problema anterior solo cambiamos la referencia del evento load por DOMContentLoaded:

<!DOCTYPE html>
<html>

<head>
    <title>Ejemplo de JavaScript</title>
    <meta charset="UTF-8">
</head>

<body>

    <form method="post" action="procesar.php" id="formulario1">
        Ingrese nombre:
        <input type="text" id="usuario" name="usuario" size="20">
        <br> Ingrese clave:
        <input type="password" id="clave" name="clave" size="20">
        <br>
        <input type="submit" id="confirmar" name="confirmar" value="Confirmar">
    </form>

    <script>
        window.addEventListener('DOMContentLoaded', inicio);

        function inicio() {
            document.getElementById("formulario1").addEventListener('submit', validar);
        }

        function validar(evt) {
            let usu = document.getElementById("usuario").value;
            let cla = document.getElementById("clave").value;
            if (usu.length == 0 || cla.length == 0) {
                alert('El nombre de usuario o clave está vacío');
                evt.preventDefault();
            }
        }
    </script>

</body>

</html>

Retornar