Eventos


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.

JavaScript implementa 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 creados a fines de 1990 y principios del 2000 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.

<html>
<head>

<script type="text/javascript">

  function validar()
  {
     var usu=document.getElementById("usuario").value;
     var 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>

</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>

</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:

<script type="text/javascript">

  function validar()
  {
     var usu=document.getElementById("usuario").value;
     var 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>

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.

<html>
<head>

<script type="text/javascript">

  window.onload=inicio;

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

  function validar()
  {
     var usu=document.getElementById("usuario").value;
     var 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>

</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>

</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()
  {
     var usu=document.getElementById("usuario").value;
     var 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 condensado:

<html>
<head>

<script type="text/javascript">

  window.onload=function() {
    document.getElementById("formulario1").onsubmit=function () {
      var usu=document.getElementById("usuario").value;
      var 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>

</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>

</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, fase);

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

<html>
<head>

<script type="text/javascript">

  window.addEventListener('load',inicio,false);

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

  function validar(evt)
  {
     var usu=document.getElementById("usuario").value;
     var 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>

</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>

</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,false);

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 y el tercer parámetro normalmente es el valor false.

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,false);
  }

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)
  {
     var usu=document.getElementById("usuario").value;
     var 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.

Retornar