2010-01-29 15 views
5

J'utilise les cases à cocher Prototype pour surveiller, afin que je puisse leur ajouter des vérifications javascript. Lorsque le tr ou le td dans lequel se trouve la case à cocher est cliqué, la case à cocher doit être cochée.
Lorsque vous cliquez directement sur une case à cocher, l'événement onchange est déclenché et vous recevez une alerte. Lorsque la valeur de la case à cocher est modifiée par javascript (lorsque vous cliquez sur le tr ou le td), onchange n'est pas activé. Pourquoi onchange n'est pas déclenché lorsque la case à cocher est modifiée indirectement?Pourquoi onchange sur une case à cocher n'est pas déclenché lorsque la case à cocher est modifiée indirectement

Ceci est le javascript que j'utilise.

Element.observe(window, 'load', function() { 
     /* If a tr or td is clicked, change the value of the checkbox. */ 
     $$('#results tr').each(function(el) { 
      el.observe('click', function(e) { 
       if(!e.target) { e.target = e.srcElement; } 
       if(e.target.nodeName == 'TD' || e.target.nodeName == 'TR') { 
        $('compare-product'+this.id).checked = ($('compare-product'+this.id).checked === false) ? true : false; 
       } 
      }); 
     }); 
     /* Monitor if the status of a checkbox has changed. */ 
     $$('#results tr td input').each(function(el) { 
       el.observe('change', function(e) { 
         alert('!'); 
        } 
       ); 
      } 
     ); 
    } 
); 

Je l'ai testé dans Firefox et IE7, les deux ne fonctionnent pas. Je ne cherche pas une solution de contournement, je suis simplement curieux de savoir pourquoi cela ne fonctionne pas.

+0

Si c'était le cas, que se passerait-il si dans votre code de gestion d'événement vous avez changé l'état de la case à cocher? –

+0

Je ne comprends pas ce que vous voulez dire. – Robin

+0

Si vous modifiez l'état dans votre même gestionnaire, le même gestionnaire d'événements sera à nouveau appelé. Si c'est le cas, vous pourriez avoir une boucle d'infini. –

Répondre

5

Cela n'est pas rare dans les frameworks d'interface utilisateur en général. Si vous modifiez l'état d'un contrôle par programmation, il est supposé que vous êtes également capable de déclencher par programmation les effets secondaires qu'il est censé avoir. Cela donne plus de flexibilité aux programmeurs et évite les bogues où l'état est en mouvement pendant l'initialisation ou le démontage. (Par exemple, lors de l'initialisation, vous pouvez définir l'état d'un contrôle avant de définir l'état de plusieurs dépendances.Si le gestionnaire de changement du premier contrôle se déclenche immédiatement, il s'exécutera alors que les autres contrôles sont dans un état incohérent.)

0

La vraie raison pour laquelle vous ne pouvez pas faire cela est parce que c'est un problème de sécurité dans le modèle de programmation. Les événements qui n'ont pas été initiés par l'utilisateur ne sont généralement pas chaînés. Donc, bien que la définition d'une valeur soit correcte, il n'est pas bon d'aller de l'avant et de déclencher tous les événements qui ont été définis sur ce contrôle. Ce que jamesdlin a dit n'a aucun sens.

Jamesdlin.

« Par exemple, lors de l'initialisation, vous pouvez définir l'état d'un contrôle avant de l'état de plusieurs pays dépendants Si le gestionnaire de changement pour les premiers feux de contrôle immédiatement, il sera exécuté alors que les autres contrôles sont dans un état incohérent . "

Cela est vrai, peu importe si vous l'avez défini par programme changez une valeur ou si vous cliquez sur le contrôle. Dans les deux cas, vous pouvez avoir d'autres contrôles dépendants.

+0

Mon point était que pendant * initialisation * certains contrôles pourraient ne pas être complètement initialisés (et pourraient donc avoir des valeurs inattendues). – jamesdlin