Salta el contingut

Gestió d'esdeveniments

Captura d'esdeveniments

Un esdeveniment és un mecanisme que desencadena l'execució de codi quan té lloc una acció determinada.
Cada acció té associada un gestor (handler) que fa de lligam entre un element HTML i la pròpia acció.

Exemple: el gestor de l'esdeveniment click (fer clic) és onclick

<img src="test.png" onclick="alert('hola')">

Podem enllaçar esdeveniments a elements HTML utiltzant un d'aquests mecanismes:

Atributs HTML d'esdeveniment

Dins del codi HTML, a la declaració d'un element li assignem un atribut amb el nom de l'esdeveniment començat per on.
El gestor de l'esdeveniment s'assigna en el moment de crear l'element HTML.

<button onclick="mostraData()">Calendari</button>

<script>
    function mostraData() {
    /// codi de la funció
    }
</script>

Funcions d'esdeveniment

En un bloc de codi Javascript, assignant una funció al mètode corresponent de l'objecte.
Localitzant la referència d'un element dins del DOM, li podem assignar una funció a l'esdeveniment:

Amb una funció amb nom

function mostraData() {
    /// codi de la funció
}

document.getElementById("boto1").onclick = mostraData

Recordatori

Com que el que volem fer és assignar la funció a l'esdeveniment, i no pas executar-la immediatament, no s'ha de posar els ( ) després del nom de la funció en fer l'assignació

Amb una funció anònima

document.getElementById("boto1").onclick = function () {
    /// codi de la funció
}

Si assignem una nova funció al mateix esdeveniment d'un element HTML, aquesta sobreescriu l'anterior i només s'executarà la darrera assignada:

function funcioUsuari1() { alert("S'executa la funció 1"); }
function funcioUsuari2() { alert("S'executa la funció 2"); }

document.getElementById("boto1").onclick = funcioUsuari1;
document.getElementById("boto1").onclick = funcioUsuari2;

La funció addEventListener

En un bloc de codi Javascript, utilitzant el mètode genèric addEventListener de l'objecte.
Localitzant la referència d'un element i assignant-li amb el mètode addEventListener.
En aquest cas, el nom de l'esdeveniment no porta el prefix on.

Amb una funció amb nom

function funcioUsuari() {
    /// codi de la funció
}

document.getElementById("boto1").addEventListener( "click", funcioUsuari );

Amb una funció anònima

document.getElementById("boto1").addEventListener( "click", function () {
    /// codi de la funció
} );

Amb aquesta sintaxi s'admet assignar més d'una funció al mateix esdeveniment.
En aquest cas, s'executaran totes en produir-se l'esdeveniment i en l'ordre en que s'han assignat a l'element:

function funcioUsuari1() { alert("S'executa la funció 1"); }
function funcioUsuari2() { alert("S'executa la funció 2"); }

document.getElementById("boto1").addEventListener( "click", funcioUsuari1 );
document.getElementById("boto1").addEventListener( "click", funcioUsuari2 );

Desvincular esdeveniments

Podem desvincular completament un esdeveniment d'un element assignant-li com a funció el valor undefined.

document.getElementById("boto1").onclick = undefined;

Si els hem vinculat amb addEventListener, podem desvincular esdeveniments selectivament amb removeEventListener.
Només podem fer-lo amb les funcions amb nom.

// Assignem una funció a l'esdeveniment click
document.getElementById("boto1").addEventListener( "click", funcioUsuari );

// Desvinculem la funció i ja no s'executarà en fer clic
document.getElementById("boto1").removeEventListener( "click", funcioUsuari );

Tipus d'esdeveniments

Hi ha molts tipus d'esdeveniments, cadascun vinculat a un grup d'accions relacionat.
Els més comuns són els de ratolí, teclat, pàgina i formulari, però també n'hi ha per multimèdia, animacions, portapapers, etc.
La llista completa es pot trobar a la pàgina de referència de la MDN.

Els més habituals són els següents:

Cancelació d'esdeveniments

Podem impedir que el navegador executi el comportament per defecte d'un esdeveniment si a la funció associada cridem el mètode preventDefault del paràmetre associat a l'esdeveniment.

document.getElementById("div2").oncontextmenu = function (e) {
    e.preventDefault();
}

Usos habituals:

  • cancel·lar el canvi d'URL en clicar un enllaç
  • cancel·lar la visualització del menú contextual
  • cancel·lar l'enviament d'un formulari en fer "submit"

Atenció

No tots els esdeveniments són cancel·lables.
Podem comprovar si un esdeveniment ho és consultant la seva propietat cancelable.

Propagació

Aturar un esdeveniment amb preventDefault NO cancel·la la seva propagació cap a altres esdeveniments.

Propagació d'esdeveniments (event bubbling)

Els esdeveniments que tenen lloc sobre un element, per defecte es propaguen a tots els seus antecessors (aquells dins dels quals estan continguts), començant pel més proper i fins al més allunyat.

Per exemple, en un cas com aquest:

<div id="div1" onclick="funcio1()">
    <div id="div2" onclick="funcio2()"></div>
</div>

En clicar sobre el div "div2", l'esdeveniment click tindrà lloc dues vegades, primer per "div2" i just després per "div1" ja que és dins del que està contingut. Per tant s'executarà primer funcio2 i després funcio1.

Perquè se'n diu event bubbling?

La propagació d'esdeveniments s'anomena "event bubbling" perquè es produeix d'abaix cap amunt, de manera similar a com una bombolla puja dins l'aigua fins arribar a la superfície, que seria l'últim element.

La propagació d'esdeveniments no sempre és desitjable, i la podem aturar invocant el mètode stopPropagation del paràmetre associat a l'esdeveniment.

element.onmouseover = function (e) {
    if ( checkbox.checked )
        e.stopPropagation();

    this.style.backgroundColor = "orange"
};

element.onclick = function (e) {
    if ( checkbox.checked )
        e.stopPropagation();

    this.style.backgroundColor = "green"
};