Quan s'utilitza DHTML tots els elements d'una pàgina poden tenir events associats, que el navegador utilitzarà per executar funcions, és a dir, tots els elements poden fer accions.

Els events es desencadenen de diverses maneres. Ja n'hem vist algunes:
  - Accions del navegador: entrar o sortir d'una pàgina, carregar imatges, detectar errades,...
 - Accions d'usuari: fer clic o moure el ratolí, prémer una tecla, ...
  - Accions del rellotge: els dos tipus de temporitzadors

Els elements d'una pàgina "disparen" els events sempre. El que nosaltres podem fer és dirigir les accions que es fan per defecte, cap a funcions que puguem controlar. Així, quan en HTML escrivim onclick="..." o bé onmouseover="...", el que fem és dirigir la sortida de l'event cap a on ens interessa. Les funcions - que, evidentment, haurem d'escriure - s'anomenen "manejadors d'events" o "Event Handlers". Dreamweaver ho tradueix per "Comportaments", i així és com les anomenarem.

Un exemple de com funciona tot plegat l'hem vist diverses vegades. Els vincles tenen, per defecte, l'event Click associat a una funció del navegador que llegeix la propietat href i l'intenta carregar. De vegades (per exemple, als enllaços buits que tant hem usat), però, no volem que s'executi aquesta funció, i dirigim l'event Click a un altre lloc que retorni "false". O sí que volem que s'executi, però, abans, volem fer una altra cosa.

Ja vam parlar sobre els events al mòdul 3, i els hem utilitzat moltes vegades. En aquesta pràctica els presentarem de forma més detallada i veurem noves possibilitats.

  Conceptes JavaScript en aquest capítol
Propietat this : referència a l'objecte que provoca un event o acció.
Objecte event : interfície JavaScript per manejar events.
Mètode captureEvents() : habilita un objecte per respondre a un tipus d'event (Netscape).

  1.- Llista d'events
Els navegadors controlen i manegen tot el que passa a través dels events, però cadascun ho fa a la seva manera, com anirem veient. La llista següent no és, doncs, massa segura i, en tot cas, intenta mostrar els mínims:

Event S'aplica a ... Passa quan ...
Abort
onabort
imatges L'usuari interromp la càrrega d'una imatge
Blur
onblur
finestres i elements de formulari El component deixa d'estar enfocat o perd el cursor
Change
onchange
camps de text i llistes de selecció Ha canviat el valor del camp
Click
onclick
botons, controls de radio i verificació, enllaços L'usuari ha fet clic sobre l'element
DragDrop
ondragdrop
finestres L'usuari fa clic i arrossega un objecte
Error
onerror
imatges i finestres La càrrega d'una imatge o pàgina produeix una errada
Focus
onfocus
finestres i elements de formulari L'element queda enfocat o rep el cursor
KeyDown
onkeydown
pàgines, imatges, vincles i àrees de text L'usuari prem una tecla
KeyPress
onkeypress
pàgines, imatges, vincles i àrees de text L'usuari prem i deixa anar una tecla
KeyUp
onkeyup
pàgines, imatges, vincles i àrees de text L'usuari deixa de prémer una tecla
Load
onload
imatges i pàgines Es carrega una pàgina o imatge
MouseDown
onmousedown
pàgines, botons i vincles L'usuari prem un botó del ratolí
MouseMove
onmousemove
per defecte, no s'aplica enlloc L'usuari mou el ratolí
MouseOut
onmouseout
mapes d'imatge i vincles El cursor del ratolí surt del mapa o vincle
MouseOver
onmouseover
vincles El cursor es situa sobre un vincle
MouseUp
onmouseup
pàgines, botons i vincles L'usuari deixa de prémer un botó del ratolí
Move
onmove
finestres La finestra es mou
Reset
onreset
formularis L'usuari esborra un formulari
Resize
onresize
finestres La finestra canvia de mida
Select
onselect
camps de text L'usuari selecciona en un camp d'entrada de text
Submit
onsubmit
formularis S'envia un formulari
Unload
onunload
cos de la pàgina L'usuari abandona la pàgina
 
2.- Definir comportaments
Un comportament, segons Dreamweaver, no és més que una funció que s'executa com a resposta a un event. N'hem vist en diverses pràctiques.

Podem definir el comportament davant d'un event de dues maneres:

- Des de HTML: <img src="bola.gif" onmouseover = "ctrlEv()">
- Des de JavaScript: document.images[0].onmouseover = ctrlEv

La definició d'un comportament es fa com qualsevol altra funció. Els comportaments poden rebre paràmetres. En tots els casos, però, hi ha un paràmetre especial, this, que s'assigna sempre i que serveix per referenciar l'objecte que ha provocat l'event. Si volem evitar que també s'executi el comportament per defecte, hem de retornar "false".

A l'exemple següent fem una funció que s'activa des de diversos llocs: quan es carrega la pàgina o quan es fa clic en un vincle. També hem posat una imatge amb un event onmouseover. Si ho provem amb els navegadors actuals, funciona; amb Netscape 4.7, no.

<script language="javascript">
function avisa( txt ) {
  alert( 'Aquesta funció s\'activa des ' + txt )
}
</script>
</head>

<body onLoad="
avisa( 'de la càrrega de la pàgina' )">
<img src="images/docs.gif" onMouseOver="
avisa( 'd\'una imatge' )">
<a href="" onClick="
avisa( 'd\'un vincle' );return false">Vincle buit</a>
...
 
3.- L'objecte Event
Per tal de manipular els events, JavaScript disposa d'una interfície, l'objecte event. Les seves propietats s'actualitzen de forma automàtica quan es produeix un event determinat, i les podem consultar per saber què ha passat, amb tota mena de detalls.

Si, en general, les diferències entre navegadors són importants, en aquest objecte hi ha un autèntic abisme. Com gairebé sempre, Internet Explorer ofereix més opcions i flexibilitat. A més, no totes les propietats es poden aplicar a tot tipus d'objectes. Si volem afinar, haurem de consultar la documentació específica de cada fabricant per a cada objecte:

Propietat Informació
x Coordenada X del ratolí, referida a la finestra
y Coordenada Y del ratolí, referida a la finestra
type Cadena (String) que representa el nom de l'event

  Les úniques propietats compatibles entre tots dos navegadors són x, y i type, de manera que, tot i que el tractament de l'objecte "event" proporciona una potència i control insospitats, pràcticament sempre haurem de detectar el navegador i oferir solucions diferents.

El plantejament del sistema d'events també és radicalment oposat entre els dos navegadors:

- Els navegadors del DOM 2 permeten que l'objecte que rep l'event el pugui processar i, si no, el passen a l'objecte pare de la jerarquia, seguin aquest ordre: vincle > contenidor > document > finestra > comportament per defecte. Pràcticament tots els objectes poden processar events.

- Netscape 4.7 fa tot el contrari, intenta processar l'event a la part més alta de la jerarquia (window) i, si no el pot manejar, el passa al seu inferior (document) fins arribar a l'objecte que l'ha generat. Això fa que pocs elements tinguin l'oportunitat de processar events.

Una forma, barroera però efectiva, de forçar Netscape 4.7 perquè processi els events, per exemple, en una capa, és escriure-hi un script intern que redefineixi el(s) comportament(s):

En aquest cas farem una capa que reaccioni als events onmouseover i onmouseout en tots dos navegadors. Després d'escriure-ho a l'etiqueta de la forma habitual, obrim un script i fem dues funcions amb el mateix nom dels events i el mateix resultat que hem definit a l'etiqueta.

<div style="position:absolute; left:100; top:80;"
onmouseover="
alert('Ratolí sobre la capa\nInternet Explorer'); "
onmouseoOut="
alert('Ratolí fora de la capa\nNavegador DOM 2'); ">
Aquí podem posar el<br>contingut de la capa
<script language="JavaScript" >

function onmouseover() {
  alert( 'Ratolí sobre la capa\nNetscape 4.7' );
}
function onmouseout() {
  alert( 'Ratolí fora de la capa\nNetscape 4.7' );
}
</script>
</div>
 
4.- Capturar events
Una manera més efectiva d'assegurar que els objectes respondran a uns determinats events és fer-ne una captura. És diferent per als dos navegadors. Amb Netscape 4.7 hem d'utilitzar el mètode captureEvents(), abans de començar. L'event es passarà com a paràmetre a la funció controladora. Explorer, en canvi, reconeix l'event dins de la funció.

Farem que la pàgina (document) capturi l'event MouseDown i el processarem amb una funció que ens dirà el tipus d'event i el lloc de la pàgina on s'ha produït. En primer lloc detectarem el navegador. A continuació, si és Netscape 4.7, fem que el document capturi l'event:

    if ( ns ) document.captureEvents( Event.MOUSEDOWN )

Si volem capturar més d'un event els podem separar amb una barra vertical:

    document.layer1.captureEvents( Event.CLICK | Event.MOUSEMOVE )

A continuació hem de fer una funció - comportament - que processi l'event:

    function processa( e ) { ... }

Finalment, hem d'enregistrar la funció com a comportaments de l'objecte:

    document.onmousedown = processa

A dins de la funció, hem de detectar si no s'utilitza Netscape 4.7 per capturar l'event de la finestra. Internet Explorer no reconeix el paràmetre, per això escrivim: if ( ! ns ) e = window.event . Finalment, amb el tipus d'objecte i les coordenades, fem un missatge d'alerta.

<script language="javascript">
var ns = document.layers
if ( ns ) document.captureEvents( Event.MOUSEDOWN )
function processa(e) {
  if( !ns ) e = window.event
  var txt = 'S\'ha capturat un event del tipus ' + e.type + '\n'
  txt += 'a la posició X: ' + e.x + ', Y: ' + e.y + '.\n'
  alert( txt )
  return true
}
document.onmousedown = processa
</script>