Comment détecter l'événement de désélection de bouton radio?

Existe-t-il un moyen simple de joindre un événement "désélectionner" sur un bouton radio? Il semble que l'événement de changement ne se déclenche que lorsque le bouton est sélectionné.

HTML

<input type="radio" id="one" name="a" /> <input type="radio" id="two" name="a" /> 

JavaScript

 $('#one').change(function() { if(this.checked) { // do something when selected } else { // THIS WILL NEVER HAPPEN // do something when deselected } });​ 

JsFiddle

Pourquoi ne créez-vous pas simplement un événement personnalisé, disons, deselect et laissez-le déclencher sur tous les membres du groupe de radio cliqué, à l'exception de l'élément lui-même qui a été cliqué? Il est plus facile d'utiliser l'API de gestion des événements que jQuery fournit de cette façon.

HTML

 <!-- First group of radio buttons --> <label for="btn_red">Red:</label><input id="btn_red" type="radio" name="radio_btn" /> <label for="btn_blue">Blue:</label><input id="btn_blue" type="radio" name="radio_btn" /> <label for="btn_yellow">Yellow:</label><input id="btn_yellow" type="radio" name="radio_btn" /> <label for="btn_pink">Pink:</label><input id="btn_pink" type="radio" name="radio_btn" /> <hr /> <!-- Second group of radio buttons --> <label for="btn_red_group2">Red 2:</label><input id="btn_red_group2" type="radio" name="radio_btn_group2" /> <label for="btn_blue_group2">Blue 2:</label><input id="btn_blue_group2" type="radio" name="radio_btn_group2" /> <label for="btn_yellow_group2">Yellow 2:</label><input id="btn_yellow_group2" type="radio" name="radio_btn_group2" /> <label for="btn_pink_group2">Pink 2:</label><input id="btn_pink_group2" type="radio" name="radio_btn_group2" /> 

JQuery

 // Attaching click event handlers to all radio buttons... $('input[type="radio"]').bind('click', function(){ // Processing only those that match the name attribute of the currently clicked button... $('input[name="' + $(this).attr('name') + '"]').not($(this)).trigger('deselect'); // Every member of the current radio group except the clicked one... }); $('input[type="radio"]').bind('deselect', function(){ console.log($(this)); }) 

Les événements de désélection ne déclencheront que parmi les membres du même groupe de radio (éléments ayant le même attribut de name ).

JsFiddle solution

EDIT: Pour tenir compte de tous les emplacements possibles de l'étiquette d'étiquette jointe (enrouler l'élément radio ou être attaché via un sélecteur d'identification), il est peut-être préférable d'utiliser onchange pour déclencher les manipulateurs. Merci à Faust d' avoir souligné cela.

 $('input[type="radio"]').on('change', function(){ // ... } 

Vous pouvez créer un événement "désélectionner" personnalisé relativement sans douleur, mais comme vous l'avez déjà découvert, l'événement de changement standard n'est déclenché que sur le bouton radio nouvellement vérifié, et non sur l'option précédemment vérifiée qui vient d'être désactivée.

Si vous souhaitez pouvoir dire quelque chose comme:

 $("#one").on("deselect", function() { alert("Radio button one was just deselected"); }); 

Ensuite, exécutez quelque chose comme la fonction suivante à partir de votre document prêt manipulateur (ou mettez le code directement dans votre document prêt manipulateur):

 function setupDeselectEvent() { var selected = {}; $('input[type="radio"]').on('click', function() { if (this.name in selected && this != selected[this.name]) $(selected[this.name]).trigger("deselect"); selected[this.name] = this; }).filter(':checked').each(function() { selected[this.name] = this; }); } 

Démonstration de travail: http://jsfiddle.net/s7f9s/2

Ce qui fait, c'est mettre un gestionnaire de clics sur toutes les radios de la page (cela ne vous empêche pas d'ajouter vos propres gestionnaires d'événements de clics aux mêmes radios) qui vérifiera si une radio précédemment sélectionnée était dans le même groupe (c.-à-d. Avec le même nom) et si ainsi, déclenchez un événement "désélectionner" sur cette radio. Ensuite, il enregistre le simple clic comme celui actuel. L'événement "désélectionner" n'est pas déclenché si vous cliquez sur la radio déjà vérifiée ou s'il n'y a pas eu de vérification préalable. Le. .filter().each() bit à la fin est de prendre en compte les radios déjà sélectionnées. (Si vous devez répondre à plus d'un formulaire sur la même page avec des groupes de radio indépendants du même nom, mettez à jour la fonction ci-dessus en conséquence).

J'ai trouvé que la façon la plus simple de le faire sans créer un nouveau cadre pour créer un événement deselected , est de changer le déclencheur d'un bouton radio pour un événement de update sur tous les boutons radio de son groupe, puis de définir le comportement que vous voulez dans le groupe Événement de mise à jour.

L'inconvénient est que le code dans la branche de désélection fonctionne même si le bouton radio n'a pas été sélectionné. Si tout ce que vous faites est une simple démonstration, une dissimulation ou une désactivation des éléments de l'interface utilisateur, cela ne devrait pas être important.

Pour utiliser votre exemple:

 buttons = $('input[name="a"]'); buttons.change(function() { buttons.trigger('update:groupA'); }).bind('update:groupA', function(){ if(this.checked) { //Do your checked things } else { //Do your unchecked things. Gets called whenever any other button is selected, so don't toggle or do heavy computation in here. } });​ 

Je pense que cela pourrait se produire parce que l'événement de focus au focus déclenche avant l'événement de change , de sorte que la prochaine radio que vous cliquez sera concentrée avant que la radio vérifiée précédente déclenche un événement de changement. Ne me citez pas sur ce …

Vous pourriez le faire comme ceci:

 var isChecked = function(id) { alert(id + ': ' + $('#' + id).is(':checked')) } $('input[name="a"]').change(function(){ isChecked('one') }) 

Demo: http://jsfiddle.net/elclanrs/cD5ww/

Je pense que vous devez ajouter la fonction de modification sur le niveau d'entrée plutôt que sur chaque bouton radio.

Essaye ça:

 $("input[name='a']").change(function() { $("input[name='a']").each(function(){ if(this.checked) { // do something when selected } else { // do something when deselected } }); });​ 

Vous pouvez déclencher l'événement «changement» vous-même. C'est un peu difficile d'éviter que les boutons radio déclenchent à l'instant un événement «change» l'un sur l'autre, mais cela peut se faire comme ceci:

 $('input[type="radio"]').each(function() { var name = $(this).attr('name'); var that = this; $('input[name="'+name+'"][type="radio"]').not(that) .on('change', function(e, alreadyTriggered) { if(!alreadyTriggered || alreadyTriggered.indexOf(this) == -1) { if(!alreadyTriggered) { alreadyTriggered = [that]; } alreadyTriggered.push(this); $(that).trigger('change', [alreadyTriggered]); } }); }); 

Voici la démo du code ci-dessus au travail.

J'ai trouvé une solution de contournement pour mon cas particulier qui pourrait vous aider. Cela fonctionne lorsque l'événement "désélectionner" peut être appliqué à tous les boutons radio qui ne sont pas sélectionnés.

Je voulais:

  1. Ajouter une classe à l'élément lorsque le boutonpoussoir a été sélectionné , et
  2. Supprimez cette classe lorsque le bouton a été "désélectionné" .

Je trouvais cette question parce que j'avais le même problème:

 $('input:radio').on('change', function() { if( $(this).is(':checked') ) { $(this).addClass('my-class-for-selected-buttons') } else { // THIS WILL NEVER HAPPEN $(this).removeClass('my-class-for-selected-buttons') } });​ 

Mais, dans mon cas, la solution était beaucoup plus facile, car je peux essayer de supprimer la classe de tous les boutons radio simplement avec jQuery, puis ajouter la classe à la sélectionnée:

 $('input:radio').on('change', function() { $('input:radio').removeClass('my-class-for-selected-buttons') // Here! if( $(this).is(':checked') ) { $(this).addClass('my-class-for-selected-buttons') } });​ 

Avec cet ajustement simple, je n'avais pas besoin de trouver un moyen de déclencher l'événement "désélectionner".

Donc, dans votre cas, vous pouvez appliquer l'événement à tous les boutons radio qui ne sont pas sélectionnés et non seulement à celui qui vient d'être «désélectionné», vous pouvez utiliser cette mesure!

Cela vous convient-il?

http://jsfiddle.net/WZND9/6/

  $('input').change(function() { if ($('#one').is(':checked')) { alert('checked'); } else { alert('not checked'); } });