estigui habilitat

En la programació tradicional, les aplicacions s’executen seqüencialment de principi a fi per produir els seus resultats. No obstant això, en l’actualitat el model predominant és el de la programació basada en esdeveniments. Els scripts i programes esperen sense realitzar cap tasca fins que es produeixi un esdeveniment. Un cop produït, executen alguna tasca associada a l’aparició d’aquest esdeveniment i quan conclou, l’script o programa torna a l’estat d’espera.

JavaScript permet realitzar scripts amb tots dos mètodes de programació: seqüencial i basada en esdeveniments . Els esdeveniments de JavaScript permeten la interacció entre les aplicacions JavaScript i els usuaris. Cada vegada que es prem un botó, es produeix un esdeveniment. Cada vegada que es prem una tecla, també es produeix un esdeveniment. No obstant això, perquè es produeixi un esdeveniment no és obligatori que intervingui l’usuari, ja que per exemple, cada vegada que es carrega una pàgina, també es produeix un esdeveniment.

El nivell 1 de DOM no inclou especificacions relatives als esdeveniments JavaScript. El nivell 2 de DOM inclou certs aspectes relacionats amb els esdeveniments i el nivell 3 de DOM inclou l’especificació completa dels esdeveniments de JavaScript. Desafortunadament, l’especificació de nivell 3 de DOM es va publicar l’any 2004, més de deu anys després que els primers navegadors incloguessin els esdeveniments.

Per aquest motiu, moltes de les propietats i mètodes actuals relacionats amb els esdeveniments són incompatibles amb els de DOM. De fet, navegadors com Internet Explorer tracten els esdeveniments seguint el seu propi model incompatible amb l’estàndard.

El model simple d’esdeveniments es va introduir a la versió 4 de l’estàndard HTML i es considera part de el nivell més bàsic de DOM . Encara que les seves característiques són limitades, és l’únic model que és compatible amb tots els navegadors i per tant, l’únic que permet crear aplicacions que funcionen de la mateixa manera en tots els navegadors.

15.1 Tipus d’esdeveniments

Cada element XHTML té definida la seva pròpia llista de possibles esdeveniments que se li poden assignar. Un mateix tipus d’esdeveniment (per exemple, punxar el botó esquerre de l’ratolí) pot estar definit per a diversos elements XHTML i un mateix element XHTML pot tenir associats diferents esdeveniments.

El nom dels esdeveniments es construeix mitjançant el prefix on, seguit del nom en anglès de l’acció associada a l’esdeveniment. Així, l’esdeveniment de punxar un element amb el ratolí s’anomena onclick i l’esdeveniment associat a l’acció de moure el ratolí es denomina onmousemove .

La següent taula resumeix els esdeveniments més importants definits per JavaScript:

Esdeveniment Descripció Elements per als quals està definit
onblur Un element perd el focus <button>, <input>, <label>, <select>, <textarea>, <body>
onchange Un element ha estat modificat <input>, <select>, <textarea>
onclick Prémer i deixar anar el ratolí Tots els elements
ondblclick Prémer dues vegades seguides amb el ratolí Tots els elements
onfocus Un element obté el focus <button>, <input>, <label>, <select>, <textarea>, <body>
onkeydown Prémer una tecla i no deixar-la anar Elements de formulari i <body>
onkeypress Prémer una tecla Elements de formulari i <body>
onkeyup Deixar anar una tecla premuda Elements de formulari i <body>
onload Pàgina carregada completament <body>
onmousedown Prémer un botó de l’ratolí i no deixar-lo anar Tots els elements
onmousemove Moure el ratolí Tots els elements
onmouseout El ratolí “surt” de l’ element Tots els elements
onmouseover El ratolí “entra” en l’element Tots els elements
onmouseup Deixar anar el botó de l’ratolí Tots els elements
onreset Inicialitzar el formulari <form>
onresize Modificar l’ mida de la finestra <body>
onselect Seleccionar un text <input>, <textarea>
onsubmit Enviar el formulari <form>
onunload s’abandona la pàgina, per exemple a l’tancar el navega dor <body>

els esdeveniments més utilitzats en les aplicacions web tradicionals són onload per esperar que es carregui la pàgina per complet, els esdeveniments onclick, onmouseover, onmouseout per controlar el ratolí i onsubmit per controlar l’enviament dels formularis.

Alguns esdeveniments de la taula anterior (onclick, onkeydown, onkeypress, onreset, onsubmit) permeten evitar l ‘ “acció per defecte” d’aquest esdeveniment. Més endavant es mostra en detall aquest comportament, que pot resultar molt útil en algunes tècniques de programació.

Les accions típiques que realitza un usuari en una pàgina web poden donar lloc a una successió d’esdeveniments. A l’prémer per exemple sobre un botó de tipus <input type="submit"> es desencadenen els esdeveniments onmousedown, onclick , onmouseup i onsubmit de forma consecutiva.

15.1.1 Manejadors d’esdeveniments

un esdeveniment de JavaScript per si mateix no té utilitat. Perquè els esdeveniments resultin útils, s’han d’associar funcions o codi JavaScript a cada esdeveniment. D’aquesta manera, quan es produeix un esdeveniment s’executa el codi indicat, de manera que l’aplicació pot respondre davant qualsevol esdeveniment que es produeixi durant la seva execució.

Les funcions o codi JavaScript que es defineixen per a cada esdeveniment s’anomenen gestor d’esdeveniments (event handlers en anglès) i com JavaScript és un llenguatge molt flexible, hi ha diverses formes diferents d’indicar els controladors:

  • manejadors com atributs dels elements XHTML.
  • Manejadors com a funcions JavaScript externes.
  • Manejadors “semàntics”.

15.1.1.1 Manejadors com atributs XHTML

Es tracta de el mètode més senzill i alhora menys professional d’indicar el codi JavaScript que s’ha d’executar quan es produeixi un esdeveniment. En aquest cas, el codi s’inclou en un atribut de el propi element XHTML. En el següent exemple, es vol mostrar un missatge quan l’usuari faci clic amb el ratolí sobre un botó:

<input type="button" value="Pinchame y verás" onclick="console.log('Gracias por pinchar');" />

En aquest mètode , es defineixen atributs XHTML amb el mateix nom que els esdeveniments que es volen utilitzar. L’exemple anterior només vol controlar l’esdeveniment de punxar amb el ratolí, el nom és onclick. Així, l’element XHTML per al qual es vol definir aquest esdeveniment, ha d’incloure un atribut anomenat onclick.

El contingut de l’atribut és una cadena de text que conté totes les instruccions JavaScript que s’executen quan es produeix l’esdeveniment. En aquest cas, el codi JavaScript és molt senzill (console.log('Gracias por pinchar');), ja que només es tracta de mostrar un missatge.

En aquest altre exemple, quan l’usuari punxa sobre l’element <div> es mostra un missatge i quan l’usuari passa el ratolí per sobre de l’element, es mostra un altre missatge:

<div onclick="console.log('Has pinchado con el ratón');" onmouseover="console.log('Acabas de pasar el ratón por encima');"> Puedes pinchar sobre este elemento o simplemente pasar el ratón por encima</div>

Aquest altre exemple inclou una de les instruccions més utilitzades en les aplicacions JavaScript més antigues:

<body onload="console.log('La página se ha cargado completamente');"> ...</body>

El missatge anterior es mostra després que la pàgina s’hagi carregat completament, és a dir, després que s’hagi descarregat el seu codi HTML, les seves imatges i qualsevol altre objecte inclòs a la pàgina.

l’esdeveniment onload és un dels més utilitzats ja que, com es va veure en el capítol de DOM, les funcions que permeten accedir i manipular els nodes de l’arbre DOM només estan disponibles quan la pàgina s’ha carregat comple tament.

15.1.1.2 Manejadors d’esdeveniments i variable this

estigui habilitat defineix una variable especial anomenada this que es crea automàticament i que es empra en algunes tècniques avançades de programació. En els esdeveniments, es pot utilitzar la variable this per referir-se a l’element XHTML que ha provocat l’esdeveniment. Aquesta variable és molt útil per exemples com el següent:

Quan l’usuari passa el ratolí per sobre de l ‘<div>, el color de la vora es mostra de color negre. Quan el ratolí surt de l’<div>, es torna a mostrar la vora amb el color gris clar original.

<div style="width:150px; height:60px; border:thin solid silver"> Sección de contenidos...</div>

Si no s’utilitza la variable this, el codi necessari per modificar el color de les vores, seria el següent:

<div style="width:150px; height:60px; border:thin solid silver" onmouseover="document.getElementById('contenidos').style.borderColor='black';" onmouseout="document.getElementById('contenidos').style.borderColor='silver';"> Sección de contenidos...</div>

El codi anterior és massa llarg i massa propens a cometre errors. Dins el codi d’un esdeveniment, JavaScript crea automàticament la variable this, que fa referència a l’element XHTML que ha provocat l’esdeveniment. Així, l’exemple anterior es pot reescriure de la següent manera:

<div style="width:150px; height:60px; border:thin solid silver" onmouseover="this.style.borderColor='black';" onmouseout="this.style.borderColor='silver';"> Sección de contenidos...</div>

El codi anterior és molt més compacte, més fàcil de llegir i d’escriure i segueix funcionant correctament encara que es modifiqui el valor de l’atribut id de l’<div>.

15.1.1.3 Manejadors d’esdeveniments com a funcions externes

La definició de controladors d’esdeveniments en els atributs XHTML és un mètode senzill però poc aconsellable per tractar amb els esdeveniments en JavaScript. El principal inconvenient és que es complica en excés pel que fa s’afegeixen algunes poques instruccions, de manera que només és recomanable per als casos més senzills.

Quan el codi de la funció manejadora és més complex, com ara la validació d’un formulari, és aconsellable agrupar tot el codi JavaScript en una funció externa que s’invoca des del codi XHTML quan es produeix l’esdeveniment.

d’aquesta manera, el següent exemple:

<input type="button" value="Pinchame y verás" onclick="console.log('Gracias por pinchar');" />

Es pot transformar en:

function muestraMensaje() { console.log('Gracias por pinchar');}

<input type="button" value="Pinchame y verás" onclick="muestraMensaje()" />

en les funcions externes no és possible utilitzar la variable this de la mateixa manera que en els manejadors inserits en els atributs XHTML. Per tant, cal passar la variable this com a paràmetre a la funció manejadora:

function resalta(elemento) { switch(elemento.style.borderColor) { case 'silver': case 'silver silver silver silver': case '#c0c0c0': elemento.style.borderColor = 'black'; break; case 'black': case 'black black black black': case '#000000': elemento.style.borderColor = 'silver'; break; }}

<div style="padding: .2em; width: 150px; height: 60px; border: thin solid silver" onmouseover="resalta(this)" onmouseout="resalta(this)"> Sección de contenidos...</div>

En l’exemple anterior, a la funció externa se li passa el paràmetre this, que dins de la funció s’anomena elemento. A el passar this com a paràmetre, és possible accedir de forma directa des de la funció externa a les propietats de l’element que ha provocat l’esdeveniment.

D’altra banda, l’exemple anterior es complica per la forma en la qual els diferents navegadors emmagatzemen el valor de la propietat borderColor. Mentre que el Firefox emmagatzema (en cas que les quatre vores coincideixin en color) el valor simple black, Internet Explorer l’emmagatzema com black black black black i opera emmagatzema la seva representació hexadecimal #000000.

15.1.1.4 manejadors d’esdeveniments semàntics

Utilitzar els atributs XHTML o les funcions externes per afegir controladors d’esdeveniments té un greu inconvenient: “embruten” el codi XHTML de la pàgina.

Com és conegut, a l’crear pàgines web es recomana separar els continguts (XHTML) de la presentació (CSS). Sempre que sigui possible, també es recomana separar els continguts (XHTML) de la programació (JavaScript). Barrejar JavaScript i XHTML complica excessivament el codi font de la pàgina, dificulta el seu manteniment i redueix la semàntica de el document final produït.

Afortunadament, hi ha un mètode alternatiu per definir els controladors d’esdeveniments de JavaScript. Aquesta tècnica consisteix a assignar les funcions externes mitjançant les propietats DOM dels elements XHTML. Així, el següent exemple:

<input type="button" value="Pinchame y verás" onclick="console.log('Gracias por pinchar');" />Se puede transformar en:

function muestraMensaje() { console.log('Gracias por pinchar');}document.getElementById("pinchable").onclick = muestraMensaje;

<input type="button" value="Pinchame y verás" />

el codi XHTML resultant és molt “net”, ja que no es barreja amb el codi JavaScript. La tècnica dels manejadors semàntics consisteix en:

  1. Assignar un identificador únic a l’element XHTML mitjançant l’atribut id.
  2. Crear una funció de JavaScript encarregada de gestionar l’esdeveniment.
  3. Assignar la funció a un esdeveniment concret de l’element XHTML mitjançant DOM.

un altre avantatge addicional d’aquesta tècnica és que les funcions externes poden utilitzar la variable this referida a l’element que original l’esdeveniment.

Assignar la funció manejadora mitjançant DOM és un procés que requereix una explicació detallada. En primer lloc, s’obté la referència de l’element a què es va a assignar el gestor:

document.getElementById("pinchable");

A continuació, s’assigna la funció externa a l’esdeveniment desitjat mitjançant una propietat de l’element amb el mateix nom de l’esdeveniment:

document.getElementById("pinchable").onclick = ...

Finalment, s’assigna la funció externa. Com ja s’ha comentat en capítols anteriors, el més important (i la causa més comuna d’errors) és indicar només el nom de la funció, és a dir, prescindir dels parèntesis a l’assignar la funció:

document.getElementById("pinchable").onclick = muestraMensaje;

Si s’afegeixen els parèntesis a la fin, en realitat s’està invocant la funció i assignant el valor retornat per la funció a l’esdeveniment onclick d’element.

l’únic inconvenient d’aquest mètode és que els gestors s’assignen mitjançant les funcions DOM, que només es poden utilitzar després que la pàgina s’ha carregat completament. D’aquesta manera, perquè l’assignació dels controladors no resulti errònia, cal assegurar-se que la pàgina ja s’ha carregat.

Una de les formes més senzilles d’assegurar que cert codi es va a executar després que la pàgina es carregui completament és utilitzar l’esdeveniment onload:

window.onload = function() { document.getElementById("pinchable").onclick = muestraMensaje;}

la tècnica anterior utilitza una funció anònima per assignar algunes instruccions a l’esdeveniment onload de la pàgina (en aquest cas s’ha establert mitjançant l’objecte window). D’aquesta manera, per assegurar que cert codi es va a executar després que la pàgina s’hagi carregat, només cal incloure-ho en l’interior de la següent construcció:

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

15.2 El flux d’esdeveniments

A més dels esdeveniments bàsics que s’han vist, els navegadors inclouen un mecanisme relacionat anomenat flux d’esdeveniments o “event flow”. El flux d’esdeveniments permet que diversos elements diferents puguin respondre a un mateix esdeveniment.

Si en una pàgina HTML es defineix un element <div> amb un botó al seu interior , quan l’usuari prem sobre el botó, el navegador permet assignar una funció de resposta a el botó, una altra funció de resposta a l’<div> que el conté i altra funció de resposta a la pàgina completa. D’aquesta manera, un sol esdeveniment (la pulsació d’un botó) provoca la resposta de tres elements de la pàgina (incloent-hi la pròpia pàgina).

L’ordre en què s’executen els esdeveniments assignats a cada element de la pàgina és el que constitueix el flux d’esdeveniments. A més, hi ha moltes diferències en el flux d’esdeveniments de cada navegador.

15.2.1 Event bubbling

En aquest model de flux d’esdeveniments, l’ordre que se segueix és des de l’element més específic fins a l’element menys específic.

En els propers exemples s’empra la següent pàgina HTML:

<html onclick="procesaEvento()"> <head><title>Ejemplo de flujo de eventos</title></head> <body onclick="procesaEvento()"> <div onclick="procesaEvento()">Pincha aqui</div> </body></html>

Quan es prem sobre el text “Fes clic aquí” que es troba dins de l’<div>, s’executen els següents esdeveniments en l’ordre que mostra el següent esquema:

Esquema de l

Figura 15.1 Esquema de l’funcionament del “event bubbling”

el primer esdeveniment que es té en compte és el generat pel <div> que conté el missatge. A continuació el navegador recorre els ascendents de l’element fins que arriba al nivell superior, que és l’element document.

Aquest model de flux d’esdeveniments és el que inclou el navegador Internet Explorer. Els navegadors de la família Mozilla (per exemple Firefox) també suporten aquest model, però lleugerament modificat. L’anterior exemple en un navegador de la família Mozilla presenta el següent flux d’esdeveniments:

Esquema de l

Figura 15.2 Esquema de l’funcionament del “event bubbling” en els navegadors de Mozilla

Encara que l’objecte window no és part de DOM, el flux d’esdeveniments implementat per Mozilla recorre els ascendents de l’element fins al mateix objecte window, afegint per tant un esdeveniment més a el model d’Internet Explorer.

15.2.2 Event capturing

En aquest altre model, el flux d’esdeveniments es defineix des de l’element menys específic fins a l’element més específic. En altres paraules, el mecanisme definit és justament el contrari a l ‘ “event bubbling”. Aquest model l’utilitzava el desaparegut navegador Netscape Navigator 4.0.

15.2.3 Esdeveniments DOM

El flux d’esdeveniments definit en l’especificació DOM suporta tant el bubbling com el capturing, però el ” event capturing “s’executa en primer lloc. Els dos fluxos d’esdeveniments recorren tots els objectes DOM des de l’objecte document fins l’element més específic i viceversa. A més, la majoria de navegadors que implementen els estàndards, continuen el flux a l’objecte window.

El flux d’esdeveniments DOM de l’exemple anterior es mostra a continuació:

Esquema de l'flux d'esdeveniments de el model DOM

Figura 15.3 Esquema de l’flux d’esdeveniments de el model DOM

l’element més específic de l’flux d’esdeveniments no és el <div> que desencadena l’execució dels esdeveniments, sinó el node de tipus TextNode que conté el <div>. El fet de combinar els dos fluxos d’esdeveniments, provoca que el node més específic pugui executar dos esdeveniments de forma consecutiva.

15.3 Handlers i listeners

A les seccions anteriors es va introduir el concepte de “event handler” o gestor d’esdeveniments, que són les funcions que responen als esdeveniments que es produeixen. A més, es van veure tres formes de definir els controladors d’esdeveniments per al model bàsic d’esdeveniments:

  1. JavaScript dins d’un atribut de l’propi element HTML
  2. Definició de l’esdeveniment en el propi element HTML però el gestor és una funció externa
  3. Manejadors semàntics assignats mitjançant DOM sense necessitat de modificar el codi HTML de la pàgina

Qualsevol d’aquests tres models funciona correctament en tots els navegadors disponibles en l’actualitat. Les diferències entre navegadors sorgeixen quan es defineix més d’un gestor d’esdeveniments per a un mateix esdeveniment d’un element. La forma d’assignar i “desassignar” controladors múltiples depèn completament de el navegador utilitzat.

15.3.1 Manejadors d’esdeveniments de DOM

L’especificació DOM defineix dos mètodes similars als disponibles per Internet Explorer i denominats addEventListener() i removeEventListener() per associar i desassociar controladors d’esdeveniments.

La principal diferència entre aquests mètodes i els anteriors és que en aquest cas es requereixen tres paràmetres: el nom del “event listener”, una referència a la funció encarregada de processar l’esdeveniment i el tipus de flux d’esdeveniments a què s’aplica.

el primer argument no és el nom complet de l’esdeveniment com succeeix en el model d’Internet Explorer, sinó que s’ha d’eliminar el prefix on. En altres paraules, si a Internet Explorer s’utilitzava el nom onclick, ara s’ha d’utilitzar click.

Si el tercer paràmetre és true, el gestor s’empra en la fase d’capturi. Si el tercer paràmetre és false, el gestor s’associa a la fase d’bubbling.

A continuació, es mostren els exemples anteriors emprant els mètodes definits per DOM:

function muestraMensaje() { console.log("Has pulsado el ratón");}var elDiv = document.getElementById("div_principal");elDiv.addEventListener("click", muestraMensaje, false); // Más adelante se decide desasociar la función al eventoelDiv.removeEventListener("click", muestraMensaje, false);

Associant múltiples funcions a un únic esdeveniment:

function muestraMensaje() { console.log("Has pulsado el ratón");} function muestraOtroMensaje() { console.log("Has pulsado el ratón y por eso se muestran estos mensajes");} var elDiv = document.getElementById("div_principal");elDiv.addEventListener("click", muestraMensaje, true);elDiv.addEventListener("click", muestraOtroMensaje, true);

Si s’associa una funció a un flux d’esdeveniments determinat, aquesta funció només es pot desassociar en el mateix tipus de flux d’esdeveniments. Si es considera el següent exemple:

function muestraMensaje() { console.log("Has pulsado el ratón");} var elDiv = document.getElementById("div_principal");elDiv.addEventListener("click", muestraMensaje, false); // Más adelante se decide desasociar la función al eventoelDiv.removeEventListener("click", muestraMensaje, true);

L’última instrucció intenta desassociar la funció muestraMensaje en el flux d’esdeveniments de capturi, mentre que a l’associar-la, es va indicar el flux d’esdeveniments de bubbling. Encara que l’execució de l’aplicació no s’atura i no es produeix cap error, l’última instrucció no té cap efecte.

15.4 L’objecte event

Quan es produeix un esdeveniment, no és suficient amb assignar-li una funció responsable de processar aquest esdeveniment. Normalment, la funció que processa l’esdeveniment necessita informació relativa a l’esdeveniment produït: la tecla que s’ha premut, la posició de l’ratolí, l’element que s’ha produït l’esdeveniment, etc..

L’objecte event és el mecanisme definit pels navegadors per proporcionar tota aquesta informació. Es tracta d’un objecte que es crea automàticament quan es produeix un esdeveniment i que es destrueix de forma automàtica quan s’han executat totes les funcions assignades a l’esdeveniment.

L’estàndard DOM especifica que l’objecte event és l’únic paràmetre que s’ha de passar a les funcions encarregades de processar els esdeveniments. Per tant, en els navegadors que segueixen els estàndards, es pot accedir a l’objecte event mitjançant l’array dels arguments de la funció:

elDiv.onclick = function() { var elEvento = arguments;}

També és possible indicar el nom argument de manera explícita:

elDiv.onclick = function(event) { ...}

El funcionament dels navegadors que segueixen els estàndards pot semblar “màgic”, ja que en la declaració de la funció s’indica que té un paràmetre, però en l’aplicació no es passa cap paràmetre a aquesta funció. En realitat, els navegadors que segueixen els estàndards creen automàticament aquest paràmetre i ho passen sempre a la funció encarregada de gestionar l’esdeveniment.

15.4.1 Propietats i mètodes

Tot i que el mecanisme definit pels navegadors per a l’objecte event és similar, existeixen nombroses diferències quant les propietats i mètodes de l’objecte.

15.4.1.1 propietats definides per DOM

La següent taula recull les propietats definides per a l’objecte event en els navegadors que segueixen els estàndards:

Propietat / Mètode Retorna Descripció
altKey boolean Retorna true si s’ha premut la tecla ALT i false en un altre cas
bubbles Boolean Indica si l’esdeveniment pertany a el flux d’esdeveniments de bubbling
button Nombre sencer el botó de l’ratolí que ha estat premut.Possibles valors: 0 – Cap botó premut 1 – S’ha premut el botó izquierdo 2 – Se ha pulsado el botón derecho 3 – Se pulsan a la vez el botón izquierdo y el derecho 4 – Se ha pulsado el botón central 5 – Se pulsan a la vez el botón izquierdo y el central 6 – Se pulsan a la vez el botón derecho y el central 7` – Es premen alhora els 3 botons
cancelable Boolean Indica si l’esdeveniment es pot cancel·lar
cancelBubble Boolean Indica si s’ha aturat el flux d’esdeveniments de tipus bubbling
charCode Nombre sencer el codi unicode de l’caràcter corresponent a la tecla premuda
clientX Nombre sencer Coordenada X de la posició de l’ratolí respecte de l’àrea visible de la finestra
clientY Nombre sencer Coordenada I de la posició de l’ratolí re specto de l’àrea visible de la finestra
ctrlKey Boolean Retorna true si s’ha premut la tecla CTRL i false en un altre cas
currentTarget element l’element que és l’objectiu de l’esdeveniment
detail nombre sencer el nombre de vegades que s’han premut els botons de l’ratolí
eventPhase Nombre sencer la fase a la qual pertany l’esdeveniment: 0 – Fase capturing 1 – En l’element destí 2 – Fase bubbling
isChar Boolean Indica si la tecla polsada correspon a un caràcter
keyCode Nombre sencer Indica el codi numèric de l’ tecla premuda
metaKey Nombre sencer Retorna true si s’ha premut la tecla META i false en un altre cas
pageX Nombre sencer Coordenada X de la posició de l’ratolí respecte de la pàgina
pageY Nombre sencer Coordenada I de la posició de l’ratolí respecte de la pàgina
preventDefault() Funció Es fa servir per cancel·lar l’acció per omissió de l’esdeveniment
relatedTarget element l’element que és l’objectiu secundari de l’esdeveniment (relacionat amb els esdeveniments de ratolí)
screenX Nombre sencer Coordenada X de la posició de l’ratolí respecte de la pantalla completa
Nombre sencer Coordenada I de la posició de l’ratolí respecte de la pantalla completa
shiftKey Boolean Retorna true si s’ha premut la tecla SHIFT i false en un altre cas
stopPropagation() Funció Es fa servir per aturar el flux d’esdeveniments de tipus bubbling
target element l’element que origina l’esdeveniment
timeStamp nombre la data i hora en què s’ha produït l’esdeveniment
type Cadena de text el nom de l’esdeveniment

A l’contrari del que passa amb Internet Explorer, la majoria de propietats de l’objecte event de DOM són de només lectura. En concret, només les següents propietats són de lectura i escriptura: altKey, button i keyCode.

La tecla META és una tecla especial que es troba en alguns teclats d’ordinadors molt antics. Actualment, en els ordinadors tipus PC s’assimila a la tecla Alt oa la tecla de Windows, mentre que en els ordinadors tipus Mac s’assimila a la tecla Command.

15.4.2 Similituds i diferències entre navegadors

15.4.2.1 Similituds

En ambdós casos s’utilitza la propietat type per obtenir el tipus d’esdeveniment que es tracta:

function procesaEvento(elEvento) { if(elEvento.type == "click") { console.log("Has pulsado el raton"); } else if(elEvento.type == "mouseover") { console.log("Has movido el raton"); }} elDiv.onclick = procesaEvento;elDiv.onmouseover = procesaEvento;

Mentre que el gestor de l’esdeveniment inclou el prefix on en el seu nom, el tipus d’esdeveniment retornat per la propietat type prescindeix d’aquest prefix.Per això en l’exemple anterior es compara el seu valor amb click i mouseover i no amb onclick i onmouseover.

Una altra similitud és l’ús de la propietat keyCode per obtenir el codi corresponent a l’caràcter de la tecla que s’ha premut. La tecla polsada no sempre representa un caràcter alfanumèric. Quan es prem la tecla ENTER per exemple, s’obté el codi 13. La barra d’espai es correspon amb el codi 32 i la tecla d’esborrat té un codi igual a 8.

una forma més immediata de comprovar si s’han premut algunes tecles especials, és utilitzar les propietats shiftKey, altKey i ctrlKey.

Per obtenir la posició de l’ratolí respecte de la part visible de la finestra, s’empren les propietats clientX i clientY. De la mateixa manera, per obtenir la posició de l’punter de l’ratolí respecte de la pantalla completa, s’empren les propietats screenX i .

15.4.2.2 diferències

Una de les principals diferències és la forma en la qual s’obté l’element que origina l’esdeveniment. Si un element <div> té assignat un esdeveniment onclick, a l’prémer amb el ratolí l’interior de l’<div> s’origina un esdeveniment l’objectiu és l’element <div>.

// Internet Explorervar objetivo = elEvento.srcElement; // Navegadores que siguen los estandaresvar objetivo = elEvento.target;

Una altra diferència important és la relativa a l’obtenció de l’caràcter corresponent a la tecla premuda. Cada tecla polsada té associats dos codis diferents: el primer és el codi de la tecla que ha estat pressionada i l’altre codi és el que es refereix a l’caràcter premut.

El primer codi és un codi de tecla intern per a JavaScript. El segon codi coincideix amb el codi ASCII de l’caràcter. D’aquesta manera, la lletra a té un codi intern igual a 65 i un codi ASCII de 97. D’altra banda, la lletra A té un codi intern també de 65 i un codi ASCII de 95.

A Internet Explorer, el contingut de la propietat keyCode depèn de cada esdeveniment. En els esdeveniments de “pulsació de tecles” (onkeyup i onkeydown) el seu valor és igual a el codi intern. En els esdeveniments de “escriure amb tecles” (onkeypress) el seu valor és igual a el codi ASCII de l’caràcter premut.

Per contra, en els navegadors que segueixen els estàndards la propietat keyCode és igual a el codi intern en els esdeveniments de “pulsació de tecles” (onkeyup i onkeydown) i és igual a 0 en els esdeveniments de” escriure amb tecles “(onkeypress).

a la pràctica, això suposa que en els esdeveniments onkeyup i onkeydown es pot utilitzar la mateixa propietat en tots els navegadors:

function manejador(elEvento) { var evento = elEvento || window.event; console.log(" El código de la tecla pulsada es " + evento.keyCode);}document.onkeyup = manejador;document.onkeydown = manejador;

en aquest cas, si es carrega la pàgina en qualsevol navegador i es prem per exemple la tecla a, es mostra el següent missatge:

missatge mostrat en el navegador Firefox

Figura 15.4 missatge mostrat en el navegador Firefox

la gran diferència es produc i a l’intentar obtenir el caràcter que s’ha premut, en aquest cas la lletra a. Per obtenir la lletra, en primer lloc s’ha d’obtenir el seu codi ASCII. Com s’ha comentat, a Internet Explorer el valor de la propietat keyCode en l’esdeveniment onkeypress és igual a el caràcter ASCII:

function manejador() { var evento = window.event;

 // Internet Explorer var codigo = evento.keyCode;} document.onkeypress = manejador;

no obstant això, en els navegadors que no són Internet Explorer, el codi anterior és igual a 0 per a qualsevol tecla premuda. En aquests navegadors que segueixen els estàndards, s’ha d’utilitzar la propietat charCode, que retorna el codi de la tecla polsada, però només per a l’esdeveniment onkeypress:

function manejador(elEvento) { var evento = elEvento;

 // Navegadores que siguen los estándares var codigo = evento.charCode;} document.onkeypress = manejador;

Un cop obtingut el codi a cada navegador, s’ha d’utilitzar la funció String.fromCharCode() per obtenir el caràcter el codi ASCII es passa com a paràmetre. Per tant, la solució completa per obtenir la tecla premuda en qualsevol navegador és la següent:

function manejador(elEvento) { var evento = elEvento || window.event; var codigo = evento.charCode || evento.keyCode; var caracter = String.fromCharCode(codigo);} document.onkeypress = manejador;

Una de les propietats més interessants és la possibilitat d’impedir que es completi el comportament normal d’un esdeveniment.En altres paraules, amb JavaScript és possible no mostrar cap caràcter quan es prem una tecla, no enviar un formulari després de prémer el botó d’enviament, no carregar cap pàgina a l’prémer un enllaç, etc. El mètode avançat d’impedir que un esdeveniment executi la seva acció associada depèn de cada navegador:

// Navegadores que siguen los estandareselEvento.preventDefault();

En el model bàsic d’esdeveniments també és possible impedir el comportament per defecte d’alguns esdeveniments. Si per exemple en un element <textarea> s’indica el següent gestor d’esdeveniments:

<textarea onkeypress="return false;"></textarea>

al <textarea> anterior no és possible escriure cap caràcter, ja que el gestor d’esdeveniments retorna false i aquest és el valor necessari per a impedir que s’acabi d’executar l’esdeveniment i per tant per evitar que la lletra s’escrigui.

Així, és possible definir controladors d’esdeveniments que tornin true o false en funció d’alguns paràmetres. Per exemple es pot dissenyar un limitador de el nombre de caràcters que es poden escriure en un <textarea>:

function limita(maximoCaracteres) { var elemento = document.getElementById("texto"); if(elemento.value.length >= maximoCaracteres ) { return false; } else { return true; }}

<textarea onkeypress="return limita(100);"></textarea>

el funcionament de l’exemple anterior es detalla a continuació:

  1. s’utilitza l’esdeveniment onkeypress per controlar si la tecla s’escriu o no.
  2. En el gestor de l’esdeveniment es torna el valor retornat per la funció externa limita() a la qual es passa com a paràmetre el valor 100.
  3. Si el valor retornat per limita() és true, l’esdeveniment es produeix de forma normal i el caràcter s’escriu al <textarea>. Si el valor retornat per limita() és false, l’esdeveniment no es produeix i per tant el caràcter no s’escriu al <textarea>.
  4. La funció limita() retorna true o false després de comprovar si el nombre de caràcters de l ‘<textarea> és superior o inferior a l’màxim nombre de caràcters que se li ha passat com a paràmetre.

l’objecte event també permet aturar completament l’execució de l’flux normal d’esdeveniments:

// Navegadores que siguen los estandareselEvento.stopPropagation();

A l’aturar el flux d’esdeveniments pendents, es invaliden i no s’executen els esdeveniments que resten des d’aquest moment fins que es recorren tots els elements pendents fins l’element window.

15.5 Tipus d’esdeveniments

La llista completa d’esdeveniments que es poden generar en un navegador es pot dividir en quatre grans g rups. L’especificació de DOM defineix els següents grups:

  • Esdeveniments de ratolí: s’originen quan l’usuari fa servir el ratolí per realitzar algunes accions.
  • Esdeveniments de teclat: s’originen quan l’usuari prem sobre qualsevol tecla del teclat.
  • Esdeveniments HTML: s’originen quan es produeixen canvis en la finestra de el navegador o quan es produeixen certes interaccions entre el client i el servidor.
  • Esdeveniments DOM: s’originen quan es produeix un canvi en l’estructura DOM de la pàgina. També es denominen “esdeveniments de mutació”.

15.5.1 Esdeveniments de ratolí

Els esdeveniments de ratolí són, amb molta diferència, els més emprats en les aplicacions web . Els esdeveniments que s’inclouen en aquesta classificació són els següents:

Esdeveniment Descripció
click es produeix quan es prem el botó esquerre de l’ratolí.També es produeix quan el focus de l’aplicació està situat en un botó i es prem la tecla ENTER
dblclick es produeix quan es prem dues vegades el botó esquerre de l’ratolí
mousedown es produeix quan es prem qualsevol botó de l’ratolí
mouseout es produeix quan el punter de l’ratolí es troba a l’interior d’un element i l’usuari mou el punter a un lloc fora d’aquest element
mouseover es produeix quan el punter de l’ratolí es troba fora d’un element i l’usuari mou el punter cap a un lloc a l’interior de l’element
mouseup es produeix quan es deixa anar qualsevol botó de l’ratolí que hagi estat premut
mousemove Es produeix (de forma contínua) quan el punter o de l’ratolí es troba sobre un element

Tots els elements de les pàgines suporten els esdeveniments de la taula anterior.

15.5.1.1 propietats

l’objecte event conté les següents propietats per als esdeveniments de ratolí:

  • les coordenades de l’ratolí (totes les coordenades diferents relatives als diferents elements)
  • La propietat type
  • La propietat srcElement (Internet Explorer) o target (DOM)
  • Les propietats shiftKey , ctrlKey, altKey i metaKey (només DOM)
  • la propietat button (només en els esdeveniments mousedown, mousemove, mouseout, mouseover i mouseup)

Els esdeveniments mouseover i mouseout tenen propietats addicionals. Internet Explorer defineix la propietat fromElement, que fa referència a l’element des del qual el punter de l’ratolí s’ha mogut i toElement que és l’element a què el punter de l’ratolí s’ha mogut. D’aquesta manera, en l’esdeveniment mouseover, la propietat toElement és idèntica a srcElement i en l’esdeveniment mouseout, la propietat fromElement és idèntica a srcElement.

En els navegadors que suporten l’estàndard DOM, només hi ha una propietat denominada relatedTarget. En l’esdeveniment mouseout, relatedTarget apunta l’element a què s’ha mogut el ratolí. En l’esdeveniment mouseover, relatedTarget apunta l’element des del qual s’ha mogut el punter de l’ratolí.

Quan es prem un botó de l’ratolí, la seqüència d’esdeveniments que es produeix és la següent: mousedown, mouseup, click. Per tant, la seqüència d’esdeveniments necessària per arribar a l’doble clic arriba a ser tan complexa com la següent: mousedown, mouseup, click, mousedown, mouseup, click, dblclick.

15.5.2 esdeveniments de teclat

els esdeveniments que s’inclouen en aquesta classificació són els següents:

Esdeveniment Descripció
keydown Es produeix quan es prem qualsevol tecla del teclat. També es produeix de forma contínua si es manté premuda la tecla
keypress Es produeix quan es prem una tecla corresponent a un caràcter alfanumèric (no es tenen en compte teles com SHIFT, ALT, etc.). També es produeix de forma contínua si es manté premuda la tecla
keyup Es produeix quan es deixa anar qualsevol tecla premuda

15.5.2.1 Propietats

L’objecte event conté les següents propietats per als esdeveniments de teclat:

  • La propietat keyCode
  • La propietat charCode (només DOM)
  • La propietat srcElement (Internet Explorer) o target (DOM)
  • Les propietats shiftKey, ctrlKey, altKey i metaKey (només DOM)

Quan es prem una tecla corresponent a un caràcter alfanumèric, es produeix la següent seqüència d’esdeveniments: keydown, keypress, keyup. Quan es prem un altre tipus de tecla, es produeix la següent seqüència d’esdeveniments: keydown, keyup. Si es manté premuda la tecla, en el primer cas es repeteixen de forma contínua els esdeveniments keydown i keypress i en el segon cas, es repeteix l’esdeveniment keydown de forma contínua.

15.5.3 esdeveniments HTML

Els esdeveniments HTML definits es recullen en la següent taula:

Esdeveniment Descripció
load es produeix en l’objecte window quan la pàgina es carrega del tot. En l’element <img> cuando se carga por completo la imagen. En el elemento `quan es carrega l’objecte
unload Es produeix en l’objecte window quan la pàgina desapareix per complet (a l’tancar la finestra de el navegador per exemple). En l’element <object> quan desapareix l’objecte.
abort Es produeix en un element <object> quan l’usuari deté la descàrrega de l’element abans que hagi acabat
error es produeix en l’objecte window quan es produeix un error de JavaScript. En l’element <img> quan la imatge no s’ha pogut carregar per complet i en l’element <object> quan l’element no es carrega correctament
select es produeix quan es seleccionen diversos caràcters d’un quadre de text (<input> i <textarea>)
change Es produeix quan un quadre de text (<input> i <textarea>) perd el focus i el seu contingut ha variat. També es produeix quan varia el valor d’un element <select>
submit es produeix quan es prem sobre un botó de tipus submit (<input type="submit">)
reset es produeix quan es prem sobre un botó de tipus reset (<input type="reset">)
resize es produeix en l’objecte window quan es redimensiona la finestra de el navegador
scroll Es produeix en qualsevol element que tingui una barra de desplaçament, quan l’usuari la fa servir. L’element <body> conté la barra de desplaçament de la pàgina completa
focus Es produeix en qualsevol element (inclòs l’objecte finestra) quan l’element obté el focus
blur Es produeix en qualsevol element (inclòs l’objecte finestra) quan l’element perd el focus

Un dels esdeveniments més utilitzats és l’esdeveniment load, ja que totes les manipulacions que es realitzen mitjançant DOM requereixen que la pàgina estigui carregada per complet i per tant, l’arbre DOM s’hagi construït completament.

l’element <body> defineix les propietats scrollLeft i scrollTop que es poden emprar juntament amb l’esdeveniment scroll.

15.5.4 Esdeveniments DOM

Tot i que els esdeveniments d’aquest tipus són part de la especificació oficial de DOM, encara no han estat implementats en tots els navegadors.La següent taula recull els esdeveniments més importants d’aquest tipus:

Esdeveniment Descripció
DOMSubtreeModified es produeix quan s’afegeixen o eliminen nodes en el subarbre d’un document o element
DOMNodeInserted es produeix quan s’afegeix un node com a fill d’un altre node
DOMNodeRemoved es produeix quan s’elimina un node que és fill d’un altre node
DOMNodeRemovedFromDocument es produeix quan s’elimina un node de el document
DOMNodeInsertedIntoDocument es produeix quan s’afegeix un node a el document

Exercici 17

Veure enunciat

Exercici 18

Veure enunciat

Exercici 19

Veure enunciat

Deixa un comentari

L'adreça electrònica no es publicarà. Els camps necessaris estan marcats amb *