Gestion des événements de case à cocher jQuery

136

J'ai ce qui suit:

<form id="myform">
   <input type="checkbox" name="check1" value="check1">
   <input type="checkbox" name="check2" value="check2">
</form>

Comment utiliser jQuery pour capturer tout événement de vérification se produisant dans myformet dire quelle case à cocher a été activée (et savoir si elle a été activée ou désactivée)?

aeq
la source

Réponses:

244
$('#myform :checkbox').change(function() {
    // this will contain a reference to the checkbox   
    if (this.checked) {
        // the checkbox is now checked 
    } else {
        // the checkbox is now no longer checked
    }
});
Darin Dimitrov
la source
30
thisest déjà défini sur l'élément DOM de la case à cocher, il this.checkedest donc suffisant. Vous n'aurez pas besoin de créer un autre objet jQuery pour lui, sauf si vous prévoyez de le manipuler.
Walf
18
Juste un petit conseil. Vous obtiendrez une amélioration des performances en utilisant input: checkbox dans votre sélecteur au lieu de simplement: checkbox puisque cette dernière est traduite en sélecteur universel *: checkbox.
jimmystormig
23
Le clic n'est à proximité d' aucun événement de contrôle.
Peter le
27
Ce n'est pas la meilleure réponse. Si vous avez une étiquette correspondante pour votre entrée (comme <label for='myInput'>Checkbox:</label><input id='myInput' name='myInput' type='checkbox'/>) et que vous cliquez sur l'étiquette, la case à cocher sera cochée, mais cette fonction ne sera PAS appelée. Vous devriez utiliser l' .change()événement
Patrick
7
Cette réponse ne fournit pas complètement la réponse - veuillez voir la réponse d'Anurag ci-dessous, qui est une réponse BEAUCOUP plus complète (et précise). Cette réponse est en partie correcte bien sûr, mais comme indiqué, ce n'est pas la meilleure réponse.
Carnix
131

Utilisez l'événement de changement.

$('#myform :checkbox').change(function() {
    // this represents the checkbox that was checked
    // do something with it
});
Anurag
la source
5
Si la case à cocher est masquée, un utilisateur ne pourra pas interagir avec elle. Faites-moi savoir si vous vouliez dire autre chose.
Anurag
1
Cela ne tire pas pour $("input[name=check1]").prop('checked', true). Voir jsfiddle.net/Z3E8V/2
Peter le
15
C'est par conception. La modification par programme de la propriété d'un élément DOM ne déclenche pas les gestionnaires d'événements associés. Vous devrez les déclencher manuellement.
Anurag le
6
Cela devrait être la réponse sélectionnée, elle couvre en cliquant sur l'étiquette d'une case à cocher
Patrick
3
De la documentation jQuery: "Comme il :checkboxs'agit d'une extension jQuery et ne fait pas partie de la spécification CSS, les requêtes utilisant :checkboxne peuvent pas tirer parti de l'amélioration des performances fournie par la querySelectorAll()méthode DOM native . Pour de meilleures performances dans les navigateurs modernes, utilisez à la [type="checkbox"]place."
NXT
54

Il existe plusieurs réponses utiles, mais aucune ne semble couvrir toutes les dernières options. À cette fin, tous mes exemples tiennent également compte de la présence d' labeléléments correspondants et vous permettent également d'ajouter dynamiquement des cases à cocher et de voir les résultats dans un panneau latéral (en redirigeant console.log).

  • L'écoute des clickévénements checkboxesn'est pas une bonne idée car cela ne permettra pas le basculement du clavier ou les modifications apportées lorsqu'un labelélément correspondant a été cliqué. Écoutez toujours l' changeévénement.

  • Utilisez le :checkboxpseudo-sélecteur jQuery plutôt que input[type=checkbox]. :checkboxest plus court et plus lisible.

  • À utiliser is()avec le :checkedpseudo-sélecteur jQuery pour tester si une case à cocher est cochée. Ceci est garanti pour fonctionner sur tous les navigateurs.

Gestionnaire d'événements de base attaché aux éléments existants:

$('#myform :checkbox').change(function () {
    if ($(this).is(':checked')) {
        console.log($(this).val() + ' is now checked');
    } else {
        console.log($(this).val() + ' is now unchecked');
    }
});

JSFiddle: http://jsfiddle.net/TrueBlueAussie/u8bcggfL/2/

Remarques:

  • Utilise le :checkboxsélecteur, ce qui est préférable à l'utilisationinput[type=checkbox]
  • Cela se connecte uniquement aux éléments correspondants qui existent au moment de l'enregistrement de l'événement.

Gestionnaire d'événements délégué attaché à l'élément ancêtre:

Les gestionnaires d'événements délégués sont conçus pour les situations où les éléments peuvent ne pas encore exister (chargés ou créés dynamiquement) et sont très utiles. Ils délèguent la responsabilité à un élément ancêtre (d'où le terme).

$('#myform').on('change', ':checkbox', function () {
    if ($(this).is(':checked')) {
        console.log($(this).val() + ' is now checked');
    } else {
        console.log($(this).val() + ' is now unchecked');
    }
});

JSFiddle: http://jsfiddle.net/TrueBlueAussie/u8bcggfL/4/

Remarques:

  • Cela fonctionne en écoutant les événements (dans ce cas change) pour remonter jusqu'à un élément ancêtre non changeant (dans ce cas #myform).
  • Il applique ensuite le sélecteur jQuery ( ':checkbox'dans ce cas) uniquement aux éléments de la chaîne de bulles .
  • Il applique ensuite la fonction de gestionnaire d'événements uniquement aux éléments correspondants qui ont provoqué l'événement.
  • Utilisez documentpar défaut pour connecter le gestionnaire d'événements délégué, si rien d'autre n'est plus proche / pratique.
  • Ne pas utiliser bodypour attacher des événements délégués car il y a un bogue (lié au style) qui peut l'empêcher d'obtenir des événements de souris.

Le résultat des gestionnaires délégués est que les éléments correspondants ne doivent exister qu'au moment de l'événement et non lorsque le gestionnaire d'événements a été enregistré. Cela permet au contenu ajouté dynamiquement de générer les événements.

Q: Est-ce plus lent?

R: Tant que les événements sont à des vitesses d'interaction utilisateur, vous n'avez pas à vous soucier de la différence de vitesse négligeable entre un gestionnaire d'événements délégué et un gestionnaire directement connecté. Les avantages de la délégation l'emportent largement sur tout inconvénient mineur. Les gestionnaires d'événements délégués sont en fait plus rapides à enregistrer car ils se connectent généralement à un seul élément correspondant.


Pourquoi ne prop('checked', true)déclenche- t-il pas l' changeévénement?

C'est en fait par conception. S'il déclenchait l'événement, vous vous retrouveriez facilement dans une situation de mises à jour sans fin. Au lieu de cela, après avoir modifié la propriété vérifiée, envoyez un événement de modification au même élément en utilisant trigger(pas triggerHandler):

par exemple sans triggerqu'aucun événement ne se produise

$cb.prop('checked', !$cb.prop('checked'));

JSFiddle: http://jsfiddle.net/TrueBlueAussie/u8bcggfL/5/

par exemple avec triggerl'événement de changement normal est intercepté

$cb.prop('checked', !$cb.prop('checked')).trigger('change');

JSFiddle: http://jsfiddle.net/TrueBlueAussie/u8bcggfL/6/

Remarques:

  • Ne l'utilisez pas triggerHandlercomme cela a été suggéré par un utilisateur, car cela ne transmettra pas d'événements à un gestionnaire d'événements délégué .

JSFiddle: http://jsfiddle.net/TrueBlueAussie/u8bcggfL/8/

mais il va travailler pour un gestionnaire d'événement directement relié à l'élément:

JSFiddle: http://jsfiddle.net/TrueBlueAussie/u8bcggfL/9/

Les événements déclenchés avec .triggerHandler () ne remontent pas dans la hiérarchie DOM; s'ils ne sont pas traités directement par l'élément cible, ils ne font rien.

Référence: http://api.jquery.com/triggerhandler/

Si quelqu'un a des fonctionnalités supplémentaires qui ne sont pas couvertes par cela, veuillez suggérer des ajouts .

Codage terminé
la source
31

Utilisation de la nouvelle méthode 'on' dans jQuery (1.7): http://api.jquery.com/on/

    $('#myform').on('change', 'input[type=checkbox]', function(e) {
        console.log(this.name+' '+this.value+' '+this.checked);

    });
  • le gestionnaire d'événements vivra
  • capturera si la case à cocher a été modifiée par le clavier, pas simplement en cliquant
Allen Hamilton
la source
1
Cela ne tire pas pour $("input[name=check1]").prop('checked', true). Voir jsfiddle.net/Z3E8V/2
Peter
7
Ajoutez simplement .triggerHandler('change');après l' .propappel. Ensuite, il basculera la case ET appellera l'événement.
Hanna
5
$('#myform input:checkbox').click(
 function(e){
   alert($(this).is(':checked'))
 }
)
Penseur
la source
val()ne vous dit pas si checkedc'est true.
Walf
5

Reconnaissant le fait que le demandeur a spécifiquement demandé jQuery et que la réponse sélectionnée est correcte, il convient de noter que ce problème n'a pas réellement besoin de jQuery en soi. Si l'on souhaite résoudre ce problème sans lui, on peut simplement définir l' onClickattribut des cases à cocher auxquelles il ou elle souhaite ajouter des fonctionnalités supplémentaires, comme ceci:

HTML:

<form id="myform">
  <input type="checkbox" name="check1" value="check1" onClick="cbChanged(this);">
  <input type="checkbox" name="check2" value="check2" onClick="cbChanged(this);">
</form>

javascript:

function cbChanged(checkboxElem) {
  if (checkboxElem.checked) {
    // Do something special
  } else {
    // Do something else
  }
}

Violon: http://jsfiddle.net/Y9f66/1/

Chase Sandmann
la source
5
Mettre les gestionnaires d'événements directement dans le HTML fonctionne bien sûr. Mais c'est en conflit direct avec les méthodologies DRY et d'amélioration progressive. Une réponse plus précise serait "Vous n'avez pas besoin de jQuery pour ajouter des gestionnaires d'événements" et à la place, en utilisant JS standard pour attacher les gestionnaires de clics dans un fichier JS séparé plutôt que de mettre des attributs onclick dans le HTML. Cela "fonctionne" mais une bonne pratique de codage vous oblige à l'éviter lorsque cela est possible (ce qui est presque toujours à ce stade, sauf si vous devez supporter IE6 ou quelque chose, ce que même MS dit que vous ne devriez plus faire)
Carnix
3

J'ai essayé le code de la première réponse, cela ne fonctionne pas mais j'ai joué et cela fonctionne pour moi

$('#vip').change(function(){
    if ($(this).is(':checked')) {
        alert('checked');
    } else {
        alert('uncheck');
    }
});
Somwang Souksavatd
la source