Welcome to Idea R | Branding - Web Agency - Digital Strategies
Switch to the mobile layout

      Idea R - Do others know who you are? Design your corporate identity

Blog

Take a software geek from the 80s, add a new generation graphic designer and dilute with a longtime marketing strategist. Shake vigorously and you'll get the Idea R's blog.

Change language... italiano

Eventi JavaScript? Che confusione!

Published on 10/28/2011
Categories: Web Design
Eventi JavaScript? Che confusione!

This article is available in English too.

Il sistema di eventi JavaScript ha tre modelli di implementazione, purtroppo tutti incompatibili tra loro.
Vediamo di fare un po' di ordine e di capire quale usare a seconda della situazione.

Il modello originale DOM 0

E' il modello base, il primo implementato, supportato da tutti i browser, ma con grosse limitazioni.
Praticamente l'event handler è trattato come una proprietà dell'oggetto che lancia l'evento.

myButton.onsubmit = myObject.onsubmiteventhandler;

Questo significa due cose importanti:

  • Non ci può essere più di un event handler per ogni evento, vale cioè sempre l'ultimo impostato che va a sostituire il precedente.
    E' possibile impostare però lo stesso event handler per eventi differenti.
  • Se viene usato l'oggetto this all'interno dell'event handler, questo farà riferimento all'oggetto scatenante (myButton nell'esempio) e non a quello che gestisce l'evento (myObject) come avviene invece nella classica programmazione Windows.

Se le limitazioni precedenti non sono un problema, per ragioni di compatibilità questo è certamente il modello da utilizzare.

Modello avanzato DOM 2

E' l'evoluzione del precedente, ma attualmente non è supportato da Internet Explorer di versione inferiore alla 9.

document.myForm.myButton.addEventListener("submit", function(e) { ... }, false);

Oppure se si vuole registrare il metodo di un oggetto (si noti che Firefox permette di usare il primo sistema per passare direttamente i metodi di un oggetto):

document.myForm.myButton.addEventListener("submit", function(e) { myObject.onsubmiteventhandler(e); }, false);

Offre le seguenti funzionalità aggiuntive:

  • Si possono registrare più event handler per lo stesso evento.
  • Agli event handler viene passato come parametro un oggetto Event con i dati significativi dell'evento stesso.
  • Se si registra più volte lo stesso event handler, tutte le registrazioni successive alla prima verranno ignorate.
  • Gli eventi vengono propagati in tre fasi consecutive:
    1. Capturing Pahase: l'evento viene propagato dall'oggetto Document seguendo la catena della discendenza fino all'oggetto finale che si era sottoscritto, a verificare se qualche antenato aveva impostato la cattura dell'evento (il terzo parametro booleano del metodo addEventListener serve appunto a specificare se la gestione deve avvenire durante questa fase).
    2. Target Node: l'evento viene gestito dall'oggetto che si è sottoscritto.
    3. Bubbling Phase: l'evento torna verso l'alto nella gerarchia, dal nodo che si è sottoscritto fino alla radice che è l'oggetto Document.

In qualsiasi momento la propagazione può essere interrotta dall'event handler in esecuzione con stopPropagation().
Per quanto riguarda invece l'oggetto this, purtroppo manca una standardizzazione, l'interpretazione più diffusa è quella identica al livello DOM 0.

Modello Internet Explorer

Supportato solo dai browser di casa Microsoft, è simile al DOM 2, ma con alcune significative differenze.

document.myForm.myButton.attachEvent("onsubmit", function(e) { ... });

  • Non implementa la Capturing Phase nella propagazione dell'evento (manca infatti il terzo parametro).
  • Se si registra più volte lo stesso event handler, questo verrà invocato più volte.
  • L'oggetto Event non viene passato come parametro all'event handler, ma è una variabile globale (window.event): questo non è un problema poiché la programmazione JavaScript è single-threaded.
  • L'oggetto this all'interno degli event handler fa riferimento all'oggetto globale window.

Vediamo ora un esempio pratico di come districarsi in queste diverse implementazioni.
Capita ad esempio spesso di dover registrare un event handler in risposta al completamento del caricamento della pagina, ma se si usasse il livello DOM 0 ci sarebbe il rischio di sovrascrivere un altro event handler precedentemente impostato. Per ovviare al problema usare la seguente funzione.

function subscribeOnLoad(eventHandler)
{
    // Check if DOM 2 level APIs are available
    if (typeof window.addEventListener != "undefined")
        window.addEventListener("load", eventHandler, false);
    // ...otherwise check if Internet Explorer APIs are available
    else if (typeof window.attachEvent != "undefined")
        window.attachEvent("onload", eventHandler);
    // ...otherwise use DOM 0 level APIs
    else
    {
        // ...if there's already an event handler
        if (window.onload != null)
        {
            var exsistingOnLoad = window.onload;
            window.onload = function (e)
                { exsistingOnLoad(e); window[eventHandler](); };
        }
        else
            window.onload = eventHandler;
    }
};

You are the reader number 14,103.

Comments

Previous article

Previous article

Centering text with CSS

Next article

Style sheets caching problems

Next article

Scroll to top