Índex
Miguel A. Almarza
Departament d'Informātica
IES Mare de Deu de la Mercè



Capítol 4.

Treball amb events

  1. Els manejadors d'events bāsics.
    1. Associació de manejadors d'events a funcions.
  2. Captura d'events dels objectes window i document.
  3. L'objecte Event, introducció.
    1. L'objecte Event segons el Netscape 4.
    2. L'objecte Event segons l'Internet explorer.
    3. L'objecte Event segons el Netscape 6.
    4. L'objecte Event en un programa pels tres navegadors.

 

4.1 Els manejadors d'events bāsics

Un manejador d'events és una funció que s'executa com a resposta a l'esdeveniment d'un event. A l'exemple següent veiem que en el moment moment de carregar un document s'esdevé un event Load que rep l'objecte BODY. El manejador d'events es la funció onLoad que que nosaltres fem igual a la funció alert. També hem fet un manejador d'events onUnLoad per a l'event Unload.

Primer manejador d'events
<HTML>
  <HEAD>
      <TITLE>Hola / Adeu</TITLE>
  </HEAD>
  <BODY onLoad="alert('Hola, benvingut.')" onUnload="alert('Adeu.')">
  </BODY>
</HTML>

 

Podem escriure més d'un manejador com a resposta a un event.
<HTML>
   <HEAD>
       <TITLE>Hola</TITLE>
   </HEAD>
   <BODY onLoad="alert('Hola')
                 alert('Que tal?')"
   >
      Cos del document.
   </BODY>
</HTML>

 

Naturalment, el manejador d'events pot ser qualsevol funció que nosaltres creem.
<HTML>
  <HEAD>
  <TITLE>Hola</TITLE>
  <SCRIPT LANGUAGE="JavaScript">
  <!--
     function benvinguda() {
     alert("hola, Benvinguts.");
     }
  // -->
  </SCRIPT>
  </HEAD>
  <BODY onLoad="benvinguda()">
  </BODY>
</HTML>

 

4.1.1 Associació de manejadors d'events a funcions.

També podem associar un event amb una funció manejadora com es fa a l'exemple següent. Aquesta forma ens permet crear fitxers de tipus .js que donen un comportament uniforme a totes les pàgines que els criden. També es una instrucciķ molt potent en cas que vulguem que la resposta a un cert event sigui sempre una resposta determinada.

Associar un event amb una funciķ manejadora.
<HTML>
 <HEAD>
 <TITLE>Hola</TITLE>
 <SCRIPT LANGUAGE="JavaScript">
   <!--
     function benvinguda() {
       alert("hola");
     }

    window.onload = benvinguda;
   // -->
 </SCRIPT>
 </HEAD>
 <BODY>
 </BODY>
</HTML>

 

Associació del manejador d'events onclick d'un botó a una funció
<HTML>
  <HEAD>
  <TITLE>Hola</TITLE>
  <SCRIPT LANGUAGE="JavaScript">
  <!--

    function fetClic() {
      alert("Has fet clic en el botó.");
    }

  // -->
  </SCRIPT>
  </HEAD>

  <BODY>
  <FORM NAME="miFormulari">
     <INPUT TYPE="button" VALUE="Fes clic" NAME="miBoto">
  </FORM>
  <SCRIPT LANGUAGE="JavaScript">
  <!--

     document.miFormulari.miBoto.onclick = fetClic;

  // -->
  </SCRIPT>
  </BODY>
</HTML>

També podem fer una funció on definirem tots els comportaments del document, funció que podem executar mitjançant l'event Load. El document següent té aquesta funció definida i es diu definicioEvents.

Definició de comportaments amb onLoad
<HTML>
  <HEAD>
  <TITLE>Hola</TITLE>
  <SCRIPT LANGUAGE="JavaScript">
  <!--

function definicioEvents() {
  document.miFormulari.miBoto.onclick = fetClic;
  }

function fetClic() {
  alert("Has fet clic.");
  }

// -->
  </SCRIPT>
  </HEAD>

  <BODY onLoad="definicioEvents()">
  <FORM NAME="miFormulari">
  <INPUT TYPE="button" VALUE="Fes clic" NAME="miBoto">
  </FORM>
  </BODY>
</HTML>

4.2 Captura d'events dels objectes window i document.

En principi qualsevol event té un destinatari objecte. Quan algú fa clic en un botó determinat el sistema operatiu (windows o altres gestors de finestres) generen un event que ha d'arribar fins a aquest botó.

Els navegadors IE6 i NS6 permeten que els objectes window i document capturin events abans que aquests events arribin a l'objecte destí d'aquests events.

Ens fixarem en el codi següent. Veiem que el document té associat la funció procesDeClic per a l'event clic. Així quan farem clic en qualsevol part del document s'executarà aquesta funció.

Això no impedeix que l'event també arribi al seu destinatari i així tenim que si fem clic a sobre del botó també s'executi la seva acció corresponent.

Captura de l'event clic per l'objecte document
<html>
  <head>
  <title>Captura d'events</title>
  <script language="Javascript">
  <!-- 
  function defineEvents(){
     document.onclick=procesDeClic;
  }
  
  function procesDeClic(){
     alert("Has fet clic en el document");
  }
  //-->
  </script>
  </head>

  <body onload="defineEvents()">
      <input type="button" onclick="alert('Hola')" value="Fes clic">
  </body>
</html>

En el NS4 tenim una forma diferent de fer aquesta captura, a través de la funció captureEvents com veieu en el codi següent:

Captura de l'event clic per l'objecte document
<html>
  <head>
  <title>Captura d'events</title>
  <script language="Javascript">
  <!-- 
  function defineEvents(){
     document.captureEvents(Event.CLICK);
     document.onclick=procesDeClic;
  }
  
  function procesDeClic(){
     alert("has fet clic en el document");
  }
  //-->
  </script>
  </head>

  <body onload="defineEvents()">
      <input type="button" onclick="alert(hola)" value="Fes clic">
  </body>
</html>

Aquesta funció té un comportament diferent ja que no permet arribar l'event al seu objecte destinatari.

Si volem fer que el nostre script sigui compatible amb els tres navegadors haurem de fer un codi com el següent:

Distinció del navegador
<html>
  <head>
  <title>Captura d'events</title>
  <script language="Javascript">
  <!--
    var nomNavegador = navigator.appName;
    var numeroVersio = parseFloat(navigator.appVersion);
    var IE=false;
    var NE4=false;
    var NE6=false;

    if (nomNavegador=='Netscape')
       if (numeroVersio >= 5) NE6 = true;
       else NE4=true;
    if (nomNavegador =='Microsoft Internet Explorer') IE=true;

    function defineEvents(){
       if (NE4) document.captureEvents(Event.CLICK);
       document.onclick=procesoDeClic;
    }
  
    function procesoDeClic(){
       alert("has fet clic en el document");
    }
  //-->
  </script>
  </head>

  <body onload="defineEvents()">
  <form>
     <input type="button" onclick="alert(hola)" value="Fes clic">
  </form>
  </body>
</html>

En aquest moment el model de maneig d'events de Netscape 4 comença a estar en desús, però encara queden molts ordinadors que fan ús d'aquesta versió del navegador. Això vol dir que encara hem de programar per a aquesta versió del navegador.

Si volem podem desactivar la captura en els dos models d'events. Amb la instrucció document.onclick=null; desactivem la captura en el model IE6, NE6 i amb document.releaseEvents(Event.CLICK); la desactivem en el model de NS4;

Captura i alliberamentde captura
<html>
<head>
<title></title>
<script language="Javascript">
<!--
  var nomNavegador = navigator.appName;
  var numeroVersio = parseFloat(navigator.appVersion);
  var IE=false;
  var NE4=false;
  var NE6=false;
  if (nomNavegador=='Netscape')
  if (numeroVersio >= 5) NE6 = true;
  else NE4=true;
  if (nomNavegador =='Microsoft Internet Explorer') IE=true;
  function procesDeClic(){
    alert("Has fet clic en el document");
  }
  function activaCaptura(){
    if (NE4) document.captureEvents(Event.CLICK);
    document.onclick=procesDeClic;
    alert("has activat captura");
  }
  function desactivaCaptura(){
   if (NE4) document.releaseEvents(Event.CLICK);
   document.onclick=null;
   alert("Has desactivat captura");
  }
   
  //-->
</script>
</head>
   <body>
<form>
<input type="button" onclick="alert('Hola del primer botón');activaCaptura();" value="Activa captura">
<input type="button" onclick="alert('Hola del segundo botón');desactivaCaptura();" value="Desactiva captura">
</form>
</body>
</html>

4.3 L'objecte Event, introducció

En el moment en que es produeix un event, com el clic del ratolí o el arrossegar o el fet d'enviar un formulari es crea un objecte Event que té unes dades comuns pe a tots els events i unes dades especifiques per a cada tipus d'events.

Així qualsevol event que es produeix té com a destinatari un objecte. Si es fa clic en un botó el destinatari d'aquest event serà aquest botó i no un altre. Si es fa clic en el teclat quan tenim el cursor en un quadre de text el destinatari serà aquest quadre de text i no el botó anterior. Es a dir que el destinatari d'un event és una dada comú a qualsevol tipus d'event.

Si fem clic amb el ratolí una dada de l'event que es produeix és un número 1, 2 o 3 que representa el botó del ratolí que ha fet clic. Quan premem una tecla del teclat, l'event que es produeix té com a dada el codi ASCII de la lletra corresponent. Es adir, que tenim dues dades totalment diferents segons l'event que es produeix.

El problema és que les versions de Javascripts dels diferents navegadors tenen diferents interfaces per a l'objecte Event. I també la forma de capturar aquest objecte per crear manejadors és diferent segons el navegadors.

Farem el mateix exemple pels tres navegadors per tal de veure les diferències i al final farem un programa únic que funcioni en els tres navegadors.

El programa serà un formulari amb dos quadres de text i un botó. En un quadre de text l'usuari escriu un nombre. Quan acaba d'escriure el nombre pot fer dues coses (produir dos events), prémer el botó o prémer la tecla intro. En els dos casos l'acció corresponent serà la d'omplir l'altre quadre de text amb la taula de multiplicar corresponent. (Veure programa executat).

4.3.1 L'objecte Event segons el Netscape 4.

En el programa de les taules de multiplicar tenim els següents objectes:

Veiem que a l'etiqueta del formulari hi ha un onSubmit="return false" que evita que l'event onSubmit es propagui i que com a conseqüència s'esborrin les dades del formulari després de prémer la tecla intro.

Formulari per al programa de taules de multiplicar (NS4)

Formulari executat
<form name="frmTaula" onSubmit="return false">
  <p>Introdueix el número per a la taula</p>
  <p> 
    <input type="text" name="txtNumTaula" >
    <input type="button" name="btnTaula" value="Fes la taula" onClick="calculaTaula()">
    <br>
    <textarea name="txtTaula" cols="40" rows="15"></textarea>
  </p>
</form>

Introdueix el número per a la taula


Bé, en un sistema de finestres com el windows, quan es produeix alguna acció sobre l'ordinador el sistema capta aquesta acció i la converteix en un objecte event que té com a destinatari un objecte dels molts que tenim per sobre de la pantalla.

Així quan estem escrivint en el quadre de text, cada vegada que premem una tecla, es produeix un event que té com a destinatari el quadre de text, que s'encarrega d'afegir la lletra corresponent al seu valor i de produir les ordres de refresc de pantalla.

Ara nosaltres hem de controlar les tecles que prem l'usuari. Hem de capturar l'event abans que arribi al seu destí i executar les accions que ens convinguin segons la tecla premuda per l'usuari.

Codi Javascript per al programa de taules de multiplicar (NS4)  
<script language="Javascript">
<!--
Inici de l'script
function defineEvents(){	  
   document.captureEvents(Event.KEYPRESS);
   document.onkeypress = controlaTecla;
}

Funció que s'encarrega de capturar l'event KEYPRESS i d'associar la seva captura amb l'execució de la funció controlaTecla.

Hem de dir que aquesta funció l'executem en l'etiqueta body en el moment en que es carrega el document.

<body onload="defineEvents()">
function controlaTecla(e) {
  var codiAsciiTecla;
  var objDesti;
  codiAsciiTecla = e.which;
  objDesti=e.target.name;   
   if ((codiAsciiTecla==13) && (objDesti == 'txtNumTaula'))
                    calculaTaula();
}  

Aquesta funció s'executa cada vegada que es captura l'event KEYPRES. Veiem que rep un objecte e de tipus Event que porta les dades corresponents.

Així en la propietat which tenim el codi ASCII i en la propietat target tenim l'objecte destí que ens permet validar l'entrada de teclat i el destinatari.

Cas que sigui la tecla intro a sobre del quadre txtNumTaula executem la funció calculaTaula i en cas contrari no fem res.

Hem de dir que l'event segueix el seu camí i arriba al seu objecte destí després d'executar-se les accions corresponents a la captura.

function calculaTaula(){
   var num = document.frmTaula.txtNumTaula.value;
   var i;
   var text="";
   if (!isNaN(num)) 
   {
     text="Taula de multiplicar del " + num + '\n';
     for(i=1;i<11;i++)
     {
        text = text + num + " * " + i + " = " + num*i + "\n";
     }
     document.frmTaula.txtTaula.value=text;
   }
   else alert("Escriu un nombre");
}
//-->
</script>
Funció que escriu la taula en el quadre de text txtTaula.

L'objecte event en el Netscape 4 té les propietats de la taula enllaçada: Taula de propietats de l'objecte Event en el Netscape 4.

 

4.3.2 L'objecte Event segons l'Internet explorer.

Codi Javascript per al programa de taules de multiplicar (IE)  
function defineEvents(){
  document.onkeypress = controlaTecla
}


Associació de l'esdeveniment de l'event (onkeypress) amb la funció que ha d'executar-se controlaTecla.

function controlaTecla() {
var codiAsciiTecla;
var objDesti;
codiAsciiTecla = window.event.keyCode;
objDesti=window.event.srcElement.name;
if ((codiAsciiTecla==13) && (objOrigen == 'txtNumTaula'))
calculaTaula();
}

Ara la funció controla les dades de l'objecte event que pertany a l'objecte window com a propietat d'aquest objecte window.

Així en el Internet Explorer no podem parlar de captura estricta de l'event.

 

L'objecte event en el Internet Explorer té les propietats de la taula enllaçada: Taula de propietats de l'objecte Event en el Internet explorer.

 

4.3.3 L'objecte Event segons el Netscape 6.

En el Javascript del NS6 varia la forma de fer la captura de l'event. Les propietats de l'objecte event que utilitzarem són les mateixes que les de l'NS4:

Codi Javascript per al programa de taules de multiplicar (NS6)  
var objFormulari;
function defineEvents(){
  objFormulari = document.getElementById("frmTaula");
  objFormulari.addEventListener("keypress", controlaTecla, true);
}

Veiem que hem de declarar una variable amb la que farem una referència a l'objecte formulari frmTaula.

Després, amb la funció addEventListener, afegim a aquest objecte un escolta que intercepta l'event keypress i que executa la funció controlaTecla quan es produeix.

<form name="frmTaula" id="frmTaula" onSubmit="return false">
Veiem que la funció getElementById ha de rebre l'identificatiu id d'un objecte. Per tant hem d'afegir id="frmTaula" en el codi de l'etiqueta form.
La funció controlaTecla(e) del NS6 és la mateixa que la del NS4 ja que el model d'events és molt semblant.  

 

L'objecte event en el Netscape 4 té les propietats de la taula enllaçada: Taula de propietats de l'objecte Event en el Netscape 6.

 

4.3.4 L'objecte Event en un programa amb l'objecte Event pels tres navegadors.

En darrer lloc fen un programa únic que serveix pels tres navegadors. Veure el programa.

Programa que fa taules de multiplicar

Captura de dades de l'objecte Event en els tres navegadors

<script language="Javascript">
<!--
    var nomNavegador = navigator.appName;
    var numeroVersio = parseFloat(navigator.appVersion);
    var IE=false;
    var NE4=false;
    var NE6=false;
    var objFormulari;

    if (nomNavegador=='Netscape')
        if (numeroVersio >= 5) NE6 = true;
        else NE4=true;
    if (nomNavegador =='Microsoft Internet Explorer') IE=true;

    function defineEvents()
    {
        if (NE4)
        {
            document.captureEvents(Event.KEYPRESS);
            document.onkeypress = controlaTecla;
        }
        if (NE6)
        {
            objFormulari = document.getElementById("frmTaula");
            objFormulari.addEventListener("keypress", controlaTecla, true);
        }
        if (IE) document.onkeypress = controlaTecla;
    }

    function controlaTecla(e) 
    {
        var codiAsciiTecla;
        var objDesti;
        if (NE4 || NE6) 
        {
            codiAsciiTecla = e.which;
            objDesti=e.target.name;
        }   
        if (IE)
        {
            codiAsciiTecla = window.event.keyCode;
            objDesti=window.event.srcElement.name;
        }
        if ((codiAsciiTecla==13) && (objOrigen == 'txtNumTaula'))
            calculaTaula();
    }  

    function calculaTaula()
    {
        var num = document.frmTaula.txtNumTaula.value;
        var i;
        var text="";
        if (!isNaN(num)) 
        {
            text="Taula de multiplicar del " + num + '\n';
            for(i=1;i<11;i++)
            {
                text = text + num + " * " + i + " = " + num*i + "\n";
            }
            document.frmTaula.txtTaula.value=text;
        }
        else alert("Escriu un número");
    }
//-->
</script>

<body bgcolor="#FFFFFF" text="#000000" onload="defineEvents()">

<h2 align="center">Càlcul de les taules de multiplicar</h2>
<form name="frmTaula" id="frmTaula" action="" method="POST" onSubmit="return false">
  <p align="center">introdueix el número per a la taula</p>
  <p align="center"> 
    <input type="text" name="txtNumTaula" >
    <input type="button" name="btnTaula" value="Fes la taula" onClick="calculaTaula()">
    <br>
    <textarea name="txtTaula" cols="40" rows="15"></textarea>
  </p>
</form>

</body>

 

Càlcul de les taules de multiplicar

introdueix el número per a la taula