JavaScript: gestione eventi cross-browser

Short link

Internet Explorer ed il W3C, almeno fino alla versione 9 di questo browser, hanno seguito due modelli distinti ed incompatibili per la gestione degli eventi. Da un lato il W3C propone i metodi addEventListener(), removeEventListener() e preventDefault(), dall'altro IE risponde con i metodi attachEvent(), detachEvent() e la proprietà returnValue. Queste sintassì gestiscono rispettivamente la creazione di un evento, la sua rimozione e l'annullamento dell'azione predefinita del browser legata ad un dato evento. In questo articolo vedremo come gestire al meglio queste differenze per giungere ad una soluzione cross-browser.

L'oggetto EventUtil

Per gestire le differenze sopra elencate, creeremo un oggetto chiamato EventUtil che avrà tre metodi pubblici:

  1. addEvent(): associa un evento ad un elemento del DOM
  2. removeEvent(): rimuove un evento da un elemento del DOM
  3. preventDefault(): impedisce l'azione predefinita legata ad un dato evento

Tale oggetto si presenta così:


var EventUtil = {
  //.. qui il codice
};

Vediamome i metodi in dettaglio.

addEvent()

Questo metodo accetta quattro parametri:

  1. element: riferimento ad un elemento del DOM
  2. eventType: il tipo di evento, per esempio click o mouseover
  3. callback: la funzione associata all'evento
  4. useCapture: valore booleano che serve a consentire o a prevenire la risalita dell'evento nel DOM (viene usato solo dai browser che supportano il modello W3C)

L'implementazione:


//.. qui il codice

addEvent: function(element, eventType, callback, useCapture) {
  
  
    if (element.addEventListener){
      element.addEventListener(eventType, callback, useCapture);
      return true;
    } else if (element.attachEvent) {
      var r = element.attachEvent('on'+ eventType, callback);
      return r;
    } else {
      alert('Impossibile generare evento');
    }

  
  
},

// continua

Si tratta di semplici costrutti if volti a verificare se il browser supporta il modello W3C o è Internet Explorer. Come si può notare, questo metodo usa entrambe le sintassi.

removeEvent()

Questo metodo accetta gli stessi parametri del metodo addEvent():


// continua

removeEvent: function(element, eventType, callback, useCapture) {
  
    if (element.removeEventListener){
      element.removeEventListener(eventType, callback, useCapture);
      return true;
    } else if (element.detachEvent) {
      var r = element.detachEvent('on'+ eventType, callback);
      return r;
    } else {
      alert('Impossibile rimuovere evento');
    }


  
},

// continua

preventDefault()

Internet Explore gestisce l'oggetto event come una proprietà dell'oggetto globale window, mentre gli altri browser non lo fanno. Questo metodo appiana questa differenza:


// continua

preventDefault: function(event) {
   
   
     event = event || window.event;
     
     if(event.preventDefault()) {
     
       event.preventDefault();
     
     } else {
     
       event.returnValue = false;
     
     }

   
   
}

Esempio pratico

Nel seguente esempio associamo una semplice animazione ad un link:


var element = document.getElementById('test');
var button = document.getElementById('enlarge');


function expandElement() {

  var widthCounter = 100;
  var heightCounter = 100;
  
  var timer = setInterval(function() {

    widthCounter++;
    heightCounter++;
    
    if(widthCounter == 200 && heightCounter == 200) {
    
      clearInterval(timer);
    
    
    }
    
    element.style.width = widthCounter + 'px';
    element.style.height = heightCounter + 'px';


  }, 25);
  
  EventUtil.preventDefault();
}

EventUtil.addEvent(enlarge, 'click', expandElement, true);

Potete visionare l'esempio finale in questa pagina.