mercoledì 14 luglio 2010

Trigger di eventi con Javascript in Internet Explorer

Esistono molti casi in cui può tornare utile far credere al browser che l'utente abbia compiuto una determinata azione. Supponiamo che in una pagina sia stata definita un'azione che viene eseguita soltanto quando l'utente fa qualcosa, ad esempio, muove il mouse sopra un elemento della pagina o preme un determinato tasto della tastiera. Tramite jQuery possiamo definire senza troppa fatica una funzione che verrà eseguita, ad esempio, ogni qual volta l'utente rilasci (dopo aver premuto) il tasto invio mentre ha il focus in un ipotetico elemento con id "inputId":

$( "#inputId" ).bind( "keyup", function (e)
{
  var keyPressed = event.keyCode;

  // 13 è il codice che corrisponde al tasto invio; 
  // è possibile conoscere facilmente il codice di ciascun tasto 
  // stampando nella console di firebug il valore della variabile keyPressed:
  if( console && console.log ) console.log("Premuto tasto con codice: " + keyPressed);

  if( keyPressed == 13 )
  {
    // fai qualcosa se è stato premuto e poi rilasciato il tasto invio
  }
});

Ora, la questione è: cosa succede se per qualsiasi motivo vogliamo che avvenga quanto abbiamo definito come gestore evento per questo evento particolare, ma senza che l'utente debba effettivamente compiere l'azione ad esso associata?

Sempre jQuery ci viene in aiuto, grazie al metodo trigger(), che permette di eseguire le azioni associate all'evento sul, o sugli, elementi selezionati, ad esempio:

$( "#inputId" ).trigger( {type: "keyup", keyCode: 13} );

il problema, però, è che questo metodo funziona benissimo su qualsiasi browser recente, fatta eccezione per Internet Explorer. Cercando un pò in giro, ho trovato questo utile plugin di jQuery:

http://updatepanel.net/2009/07/09/jquery-fire-event-plugin/

che permette di ovviare al problema manifestato in Internet Explorer. Per le mie necessità ho avuto bisogno di modificarlo leggermente: avevo bisogno di poter personalizzare le proprietà dell'oggetto evento generato dal plugin, prima di farlo propagare al/agli elementi selezionati dall'oggetto jQuery.

Questo il codice del plugin con le mie modifiche:

$.fn.fireEvent = function(eventType, properties) 
{
  var e = function(a, b)
  {
    for(var p in b)
    {
      a[p] = b[p];
    }
    
    return a;
  };

  if( ! properties )
  { 
    properties = {} ;
  };

  return this.each(function() 
  {
    if (document.createEvent) 
    {
      var event = document.createEvent("HTMLEvents");
      event.initEvent(eventType, true, true);
      event = e(event, properties);
      
      return !this.dispatchEvent(event);
    } 
    else 
    {
      var event = document.createEventObject();
      event = e(event, properties);
      
      return this.fireEvent("on" + eventType, event);
    }
  });
};

Che si può poi utilizzare in questo modo per ottenere l'effetto che ci eravamo prefissi all'inizio dell'articolo, ma questa volta ottenendo anche la compatibilità in Internet Explorer (testato in IE8):

$("#inputId").fireEvent( "keyup", {keyCode:13} );

Nessun commento:

Posta un commento