2010-01-18 5 views
0

J'ai un bouton radio, contenant une ligne onclick événement:ajouter Fiable à un événement Javascript

<input type="radio" class="quantitycheckbox" onclick="alterQuantity(this.form)"> 

Je suis en train de discrètement ajouter un peu plus de fonctionnalités sur clic, et ont ce code:

function updateCustomFields(box) { 
    // save current onclick event before assigning new one 
    var currEvent = box.onclick; 
    box.onclick = function() { 
     currEvent(); 
     // do additional stuff here 
    } 
} 

var boxes = $class('quantitycheckbox'); 
for(var i = 0; i < boxes.length; i++) { 
    updateCustomFields(boxes[i]); 
} 

Toutefois, la valeur de this.form transmise à la fonction alterQuantity n'est pas définie et une erreur se produit. Comment préserver l'événement onclick tel quel et ajouter mes fonctionnalités?

Répondre

2

Vous n'avez rien à faire avec l'événement inline onclick. En attachant un autre événement à l'aide attachEvent ou addEventListener résoudra votre problème puisque l'événement en ligne onclick se déclenche toujours d'abord:

function updateCustomFields(box) { 
    var myCallback = function(){ 
     // Do stuff here 
    } 
    if(window.addEventListener){ 
     box.addEventListener('click', myCallback, false); 
    } else if (window.attachEvent){ 
     box.attachEvent('onclick', myCallback); 
    } 
} 

L'ordre d'exécution sera:

  1. événements en ligne
  2. Votre nouvel événement
+0

Comment est-ce la bonne façon? Et où est-il documenté qu'un gestionnaire d'événements défini via la propriété 'onclick' est garanti de se déclencher en premier dans tous les navigateurs? –

+1

@Tim, les événements sont toujours exécutés dans l'ordre. Comme les gestionnaires onclick en ligne sont d'abord "enregistrés" (vous ne pouvez pas ajouter d'événement à un élément DOM tant qu'il n'existe pas, et dès qu'il existe, le gestionnaire inline est déjà attaché à l'élément). C'est la manière * correcte * à cause de la force avec laquelle je pense que la logique doit être séparée de la structure. Je pense que je voulais être entre guillemets donc ça révèle mon parti pris ... Je vais éditer :) –

+0

L'interaction entre les événements en ligne et la norme W3 DOM Events (sans parler du mess d'IE) n'est pas normalisée du tout. Bien que lorsque IE, Mozilla, WebKit et Opera sont tous d'accord sur quelque chose que vous êtes généralement sur un gagnant. – bobince

1

Essayez:

currentEvent.call(box); 

pour passer box comme valeur de this dans currentEvent();

éditer: La solution de Doug est réellement meilleure. Quoi qu'il en soit, les méthodes call et apply disponibles pour tous les objets de fonction est comment vous modifiez la valeur de ce dans les appels de fonction.

+0

Je pense que le problème est que 'this.form' n'est jamais passé, pas la valeur de' this'. Aucune information d'argument n'est conservée quand il appelle 'currEvent();'. –

+1

Cela peut également être fait avec 'call':' currentEvent.call (box, box.form) '. – bobince

+0

@Jon: Ce que vous ne réalisez pas, c'est que currentEvent ressemble à ceci: 'function() {alterQuantity (this.form)}'. La fonction 'alterQuantity()' est compilée en tant que corps du gestionnaire d'événements, et non en tant que gestionnaire d'événements. Il suffit donc de passer 'this' pour passer' this.form' à 'alterQuantity()'. – slebetman

Questions connexes