Fins ara hem vist totes les accions realitzades amb JavaScript com a part de la secció body, de tal manera que quan es carrega la pàgina, s'executa el codi corresponent de forma gairebé instantània. En aquesta pràctica s'introdueix dos elements més del llenguatge: les funcions i els events.

Sobre els events es farà un anàlisi introductori, per poder-los utilitzar conjuntament amb les funcions, posteriorment, al mòdul 7 pràctica 1 s'analitzaran amb més detall.

Per event s'entén qualsevol cosa que passi en l'entorn provocada per les accions del propi usuari o bé pel canvi d'estat d'algun objecte.

Per exemple, quan l'usuari fa clic a sobre d'un botó amb el ratolí esta provocant un event, un altre exemple podria ser quan una pàgina acaba de carregar-se completament al navegador.

Quan estem interaccionant amb una pàgina, s'estan produint events constantment, ara bé, això no vol dir que a nosaltres, com a programadors de la web, ens hagin d'interessar tots i per tant no en farem cap cas a la majoria d'ells.

Però, si algun event interessa tractar-lo d'una forma específica, l'haurem de detectar mitjançant els controladors d'events, i posteriorment s'hagi detectat, efectuarem unes accions determinades que, generalment, estaran descrites dins una funció.

Les funcions ens serviran per agrupar blocs de codi de programa que realitzaran unes accions específiques. Aquests blocs de codi tindran un nom: el nom de la funció.

Les funcions han de ser d'ús general, es a dir, les hem de poder utilitzar en múltiples situacions similars. Cada situació ha de poder tenir uns valors diferents a tractar per part de la funció. Per facilitar l'afirmació anterior es disposa dels paràmetres que passarem a la funció.



  Elements del llenguatge en aquest capítol.
Declaració function : Declara el bloc de codi que correspon a una funció.
Controlador d'events on... : Permet detectar i tractar un determinat event.
Sentència return : Ens retorna un valor resultant de la funció al lloc on s'ha invocat.
Objecte Math : Ofereix mètodes per fer tractaments matemàtics dels valors numèrics.
Mètode round : Arrodoneix un valor amb decimals al valor sencer més proper.
Mètode random : Retorna un valor numèric aleatori entre 0 i 1.
 
1.- Els events. Ha passat alguna cosa?
Es diu de JavaScript que és un llenguatge de programació orientat a events. Però, què és un event? Un event és qualsevol cosa que passa en el l'àmbit d'acció del programa.

Per exemple, cada cop que fem un clic amb el ratolí , passem el ratolí per sobre d'un objecte, canviem la grandària d'una finestra, es tanca una finestra, etc. s'està provocant un event. La majoria dels events que es produeixen no tenen cap interès en el funcionament del programa i són ignorats.

Però, en algunes situacions ens pot interessar que el programa faci algunes accions específiques quan es produeix un determinat event. En aquests casos, hem de detectar-lo i fer que el programa actuï en conseqüència.

La següent llista ens mostra algun dels events més habituals :

blur.- es produeix quan un element de formulari perd el focus, per exemple, quan es fa clic a un altre lloc diferent d'aquest element.
click.- es produeix quan es fa un clic amb el ratolí a sobre d'un element.
change.- es produeix quan l'usuari canvia el valor d'un camp de formulari.
focus.- es produeix quan un element rep el focus.
load.- es produeix quan es carrega una pàgina en el navegador.
mouseover.- es produeix quan l'usuari mou el cursor per sobre d'un vincle d'hipertext.
submit.- es produeix quan es fa clic a sobre del botó per a enviar les dades d'un formulari.
unload.- es produeix quan l'usuari abandona una pàgina.
etc.

Per detectar un event s'utilitza els controladors d'events, aquests elements de programa tenen una estructura com la següent:

        onXXXX = codi d'accions a realitzar;

Les lletres XXXX indiquen el tipus d'event a detectar i el codi indicat a l'esquerra de símbol = serà l'acció a realitzar quan es produeixi aquest event.

Els controladors d'event corresponents als events indicats anteriorment són els següents.

      onBlur, onClick, onChange, onFocus, onLoad, onMouseOver, onSubmit i onUnLoad

Aquests controladors s'apliquen dins les directives HTML que els poden suportar amb l'estructura indicada prèviament.

S'ha de tenir en compte que si un element de codi HTML que incorpora un controlador d'event està inclòs dins una altre element que també incorpora un altre controlador d'event, l'element inclòs heretarà també l'event de l'element que l'inclou. A aquest efecte se l'anomena bombolleig d'events.

Si el codi que ha d'executar un controlador d'events és molt extens, no s'acostuma a incloure a la dreta del signe = . Habitualment, se sol definir una funció que inclou tot el codi que ha d'executar l'event i solament s'assigna el nom de la funció al controlador d'events. En els apartats següents es pot veure com es treballa amb funcions i events.

El següent exemple ens mostra com són utilitzats alguns dels events indicats prèviament. L'efecte que produeix la detecció de cada event és molt simple: ens traurà un missatge d'alerta quan l'event sigui detectat. El codi a executar serà el mètode "alert" ubicat després del signe =.

Podem observar com dins la directiva <body> hi ha situats els events onLoad i onUnload.

        <body ..... onLoad="alert('S\'ha carregat la pàgina.');"  onUnload="alert('Adéu.');">

Aquests events mostraran un missatge quan es carregui la pàgina i quan es descarregui.

Dins la primera fila de la taula hi ha definits dos events, l'un dins de <td> i l'altre dins de <p>, com que <p> està inclòs dins de <td> es produeix un efecte de bombolleig d'events al fer un clic a sobre del text "Text 1", per tant, es mostraran dos missatges d'alerta.

      <tr ... ><td ... onClick="alert('Bombolleig d\'events.');">
                    <p onClick="alert('Has fet un clic a sobre de Text 1.');">Text 1.</p></td></tr>


A la segona fila de la taula s'hi aplica el controlador d'event onMouseover, per tant, cada cop que passem el ratolí per sobre se'ns mostrarà el corresponent missatge d'alerta.

      <p onMouseOver="alert('Has passat el  ratolí per sobre de Text 2.');">Text 2.</p>

Dins el formulari, s'apliquen quatre controladors d'events, el primer és onSubmit, que s'activarà quan fem clic a sobre el botó "Clica'm". L'event onChange el podrem observar cada cop que canviï el contingut del "Quadre 1" i l'event onBlur, s'activarà cada cop que el "Quadre 2" perdi el focus.

Els events sobre "Text 1" i "Text 2" no es podran observar amb el navegador Netscape 4.x. Aquest navegador reconeix molts menys events i efectua un tractament dels events de forma molt diferent a com ho fan els navegadors Internet Explorer i Netscape 6.x.

<html>
<head>
<title>Exemple</title>
</head>
<body bgcolor="#E0E8E0"
onLoad="alert('S\'ha carregat la pàgina.');"
                                                                      onUnload="alert('Adéu.');">
    <table border="1" align="center">
    <tr align="center"><td bgcolor="#ffffcc"
onClick="alert('Bombolleig d\'events.');">
        <p
onClick="alert('Has fet un clic a sobre de Text 1.');">Text 1.</p></td></tr>
    <tr align="center"><td bgcolor="#66ffcc"><p
onMouseOver="alert('Has passat el
                                              ratolí per sobre de Text 2.');">Text 2.</p></td></tr>
    </table>
    <center>
    <form
onSubmit="alert('Ho sento, aquest formulari no pot enviar res.');
                                                                                              return false;">
    Quadre 1: <input type="text"
onChange="alert('Ha canviat el contingut del
                                                                                         Quadre 1.');"><br>
    Quadre 2: <input type="text"
onBlur="alert('El Quadre 2 ha perdut el focus.');"><br>
    <input type="submit" value="Clica'm">
    </form>
    </center>
</body>
</html>


 
2.-
Què són les funcions?

Una funció és un bloc de codi al que li donem un nom específic: el nom de la funció. Aquest bloc de codi realitzarà unes accions determinades i el podrem invocar tantes vegades com desitgem, des de qualsevol altre lloc de la plana web, escrivint el seu nom.

El nom de la funció sempre anirà seguit de dos parèntesi ( ). Dins aquest parèntesi hi podrà haver, o no, els paràmetres separats amb comes , . Les accions que ha de realitzar la invocació de la funció han d'estar situades entre claus { }.

Els paràmetres són valors que es passen a la funció, de tal manera que, el comportament de la funció pot ser modificat segons quins siguin els paràmetres que se li han passat. En una funció hi pot haver molts paràmetres dins el parèntesi o no haver-ni cap. En cas de no haver-hi cap paràmetre no es pot obviar la utilització dels dos parèntesi ( ) al final del nom de la funció.

La sintaxi genèrica d'una funció és la següent:

         nom_funcio( paràmetre1, paràmetre2, paràmetre3, ..... )
         {
               ......... Accions a realitzar per la funció ...............
               .........Finalitzem amb return únicament si s'ha de retornar algun valor.........
         }


En qualsevol altre lloc del codi es pot invocar a la funció indicant el seu nom i els paràmetres entre parèntesi. Si la funció ens ha de retornar algun resultat el podem assignar a una variable.

Invocació sense que retorni cap valor (només realitzarà accions):

               nom_funcio(valor1, valor2, .....);

Invocació retornant un valor resultant (també pot realitzar accions, a més a més):

               variable = nom_funcio(valor1, valor2, .....);

S'ha de tenir en compte que els paràmetres són opcionals i que si no n'hi ha cap, els parèntesi s'han de mantenir.

Habitualment les funcions se solen definir dins el bloc <head> del codi HTML, encara que no hi ha cap inconvenient que estiguin definides dins el bloc <body>

En el següent exemple podem veure com invoquem a una funció i li passem uns paràmetres. La funció de nom escriu s'encarrega d'escriure a la finestra activa indicant el valors dels paràmetres que li hem passat.

La invocació de la funció es provoca quan es detecta l'event Clic sobre un botó, per tant en aquest exemple, també podem observar una utilització molt habitual dels events que invoquen a una funció, en lloc, d'executar el codi directament tal com s'ha fet a l'apartat sobre events.

<html>
<head>
<title>Exemple</title>
<script language="JavaScript">
  function escriu(parametre1, parametre2, parametre3)
  {
    document.writeln("Acabes d'invocar a la funció <b>escriu</b> i li has passat
                              els següents paràmetres:");
    document.writeln("<br>El primer paràmetre és: <font color='#FFOOOO'>"
                              + parametre1+ "</font>");
    document.writeln("<br>El segon paràmetre és: <font color='#FFOOOO'>"
                              + parametre2 + "</font>");
    document.writeln("<br>El tercer paràmetre és: <font color='#FFOOOO'>"
                              + parametre3 + "</font><p>");
  }
</script>
</head>

<body bgcolor="#E0E8E0">
<form name="form1">
<table border="0" width="370" align="center">
  <tr><td align="right">Primer paràmetre:</td><td align="center">
                              <input type="text" name="param1" value="A"></td></tr>
  <tr><td align="right">Segon paràmetre:</td><td align="center">
                              <input type="text" name="param2" value="B"></td></tr>
  <tr><td align="right">Tercer paràmetre:</td><td align="center">
                              <input type="text" name="param3" value="C"></td></tr>
  <tr><td colspan="2" align="center"><input type="button" value="Prem aquí"
              onClick="
escriu(param1.value, param2.value, param3.value)"></td></tr>
</table>
</form>
</body>
</html>


 
3.- Les funcions ens poden retornar resultats.
En l'exemple anterior, hem invocat una funció passant-li uns paràmetres i ella ha fet les accions que tenia programades i que consistien en mostrar el valors dels tres paràmetres passats.
També podem fer que la funció ens retorni un resultat al lloc des d'on s'ha invocat.

El següent exemple mostra com mitjançant la sentència return podem retornar un valor resultant al lloc que ha invocat a la funció. La següent línia dins la funció s'encarrega de retornar el valor que s'indica a continuació de return.

                                return parametre1 + " " + parametre2;

De fet, el codi de la funció és molt simple. Retorna la concatenació ( + )de les cadenes de text passades com a paràmetres amb un espai en blanc enmig.

Al mateix temps, des del formulari form1 situat dins del bloc <body>, en el mateix lloc on s'ha invocat la funció, assignem el valor retornat a la propietat value del quadre de text de nom resul.

                              resul.value=escriu(param1.value, param2.value)

És a dir, en fer el clic sobre el botó, es provoca un event que és detectat pel controlador d'events onClick. Aquest controlador d'events invoca la funció escriu() i li passa com a paràmetres el contingut de param1.value i param2.value. Un cop processada la funció, aquesta retorna un resultat i s'assigna a resul.value.
<html>
<head>
<title>Exemple</title>
<script language="JavaScript">
   function escriu(parametre1, parametre2)
  {
      return parametre1 + " " + parametre2;
  }
</script>
</head>

<body bgcolor="#E0E8E0">
<form name="form1">
<table border="0" width="370" align="center">
    <tr><td align="right">Primer paràmetre:</td><td align="center">
                              <input type="text" name="param1" value="A"></td></tr>
    <tr><td align="right">Segon paràmetre:</td><td align="center">
                              <input type="text" name="param2" value="B"></td></tr>
    <tr><td align="right">Valor retornat:</td><td align="center">
                              <input type="text" name="resul" value=""></td></tr>
    <tr><td colspan="2" align="center"><input type="button" value="Prem aquí"
                    onClick="
resul.value=escriu(param1.value, param2.value)"></td></tr>
</table>
</form>
</body>
</html>


 
4.- Evitem les repeticions.
Les funcions ens han de servir per reduir i estructurar el codi.

Referent a l'estructuració del codi del programa, en veurem un petit exemple descriptiu al mòdul 8 pràctica 3. Aquí, en canvi, veurem un exemple en què utilitzarem les funcions per reduir la grandària del codi.

Suposem que hem d'escriure un tros de codi que s'ha de repetir moltes vegades. Si aquest codi és extens, provocarà que el programa sigui massa llarg de forma innecessària.

La millor solució per evitar això és incloure aquest codi dins una funció i, a tots els llocs on s'hagi de repetir, invocarem la funció simplement escrivint el seu nom. Si a més, desitgem que aquest codi faci les accions de forma diferent en funció d'unes variables, podem posar a la funció els paràmetres apropiats.

El següent exemple pretén il·lustrar aquest concepte. Es pretén crear una taula on cadascuna de les caselles tingui un color diferent de forma aleatòria. Mitjançant codi, creem la taula de forma dinàmica i apliquem a cada cel·la el paràmetre "bgcolor".

El valor del color assignat a bgcolor, el determinem de forma aleatòria a partir d'una llista de colors ubicada dins un Array. Per fer la selecció aleatòria utilitzem els mètodes random() i round() de l'objecte Math. El codi per fer la selecció està ubicat dins la funció color( ) que retorna el nom del color corresponent. Aquesta funció no té paràmetres.

Posteriorment, dins la taula s'invoca la funció color() cada cop que es desitja obtenir un color aleatori d'entre els de la llista.

Es pot apreciar que l'ús de la funció redueix bastant l'extensió del codi, ja que en cas contrari, el codi de la funció color() s'hauria de repetir tantes vegades com cel·les tenim, en canvi, ara solament ha calgut repetir el nom de la funció.

<html>
<head>
<script language="JavaScript">
    function color()
    {
        var colors=new Array("black", "blue", "brown", "fuchsia", "green",
                                                        "magenta", "orange", "red", "yellow");
        return colors[Math.round(9 * Math.random() - 0.5)];
    }
</script>
</head>
<body>
<script language="JavaScript">
    document.writeln('<table border="1" width="350" align="center" >');
    document.writeln('<tr><td bgcolor="' +
color() + '">&nbsp;</td><td bgcolor="'
          +
color() + '">&nbsp;</td><td bgcolor="' + color() + '">&nbsp;</td><td
          bgcolor="' +
color() + '">&nbsp;</td></tr>');
    document.writeln('<tr><td bgcolor="' +
color() + '">&nbsp;</td><td bgcolor="'
          +
color() + '">&nbsp;</td><td bgcolor="' + color() + '">&nbsp;</td><td
          bgcolor="' +
color() + '">&nbsp;</td></tr>');
    document.writeln('<tr><td bgcolor="' +
color() + '">&nbsp;</td><td bgcolor="'
          +
color() + '">&nbsp;</td><td bgcolor="' + color() + '">&nbsp;</td><td
          bgcolor="' +
color() + '">&nbsp;</td></tr>');
    document.writeln('<tr><td bgcolor="' +
color() + '">&nbsp;</td><td bgcolor="'
          +
color() + '">&nbsp;</td><td bgcolor="' + color() + '">&nbsp;</td><td
          bgcolor="' +
color() + '">&nbsp;</td></tr>');
    document.writeln('</table>');
</script>
</body>
</html>