jQuery Click se déclenche deux fois en cliquant sur l’étiquette

J’utilise jQuery pour créer des boutons radio personnalisés et j’ai un problème. En cliquant sur l’étiquette associée à la radio, les événements de clic se déclenchent deux fois, si je clique uniquement sur la radio elle-même, cela fonctionne très bien (en fait Voici le code:

Le HTML:

RADIO1 RADIO2 RADIO3

jQuery:

  $(function () { $('#box').find('input:radio').each(function (i) { var input = $(this); // get the associated label using the input's id var label = $('label[for=' + input.attr('id') + ']'); // wrap the input + label in a div $('
').insertBefore(input).append(label, input); var wrapperDiv = input.parent(); // find all inputs in this set using the shared name atsortingbute var allInputs = $('input[name=' + input.attr('name') + ']'); // necessary for browsers that don't support the :hover pseudo class on labels label.hover( function () { $(this).addClass('hover'); }, function () { $(this).removeClass('hover checkedHover'); }); //bind custom event, sortinggger it, bind click,focus,blur events wrapperDiv.bind('updateState', function () { if ($(this)[0].children[1].checked) { allInputs.each(function () { var curDiv = $('div > label[for=' + $(this).attr('id') + ']').parent(); curDiv.removeClass('custom-radio-checked'); curDiv.addClass('custom-radio'); }); $(this).toggleClass('custom-radio custom-radio-checked'); } else { $(this).removeClass('custom-radio-checked checkedHover checkedFocus'); } }) .sortinggger('updateState') .click(function () { console.log('click'); }) .focus(function () { label.addClass('focus'); }).blur(function () { label.removeClass('focus checkedFocus'); }); }); });

Y a-t-il une solution pour ce comportement?

Essayez d’append:

 evt.stopPropagation(); evt.preventDefault(); 

au .bind () ou .click (), selon ce que vous voyez. Ajoutez également le paramètre evt à la fonction, comme function(evt) {...

J’ai essayé d’append la solution ci-dessus en ajoutant:

 evt.stopPropagation(); evt.preventDefault(); 

mais n’a pas fonctionné. Cependant, en ajoutant ceci:

 evt.stopImmediatePropagation(); 

résolu le problème! 🙂

Liez l’événement click à l’entrée plutôt qu’à l’étiquette. Lorsque l’utilisateur clique sur l’étiquette, l’événement se produit toujours car, comme l’a mentionné Dustin, un clic sur l’étiquette déclenche un clic sur l’entrée. Cela permettra à l’étiquette de conserver ses fonctionnalités normales.

 $('input').click(); 

Au lieu de

 $('label').click(); 

Si vous essayez d’utiliser un conteneur externe en tant qu’élément de clic, vous pouvez également laisser les événements bouillonner naturellement et tester l’élément attendu dans votre gestionnaire de clic. Ce scénario est utile si vous essayez de définir une zone de clic unique pour un formulaire.

 

Pour résoudre ce problème facilement, supprimez l’atsortingbut “for” sur l’étiquette. Un clic sur l’étiquette déclenchera également un clic sur l’élément associé. (qui dans votre cas déclenche votre événement click deux fois)

Bonne chance

J’utilise habituellement cette synthax

 .off('click').on('click', function () { console.log('click'); }) 

au lieu de

 .click(function () { console.log('click'); }) 

Le problème avec e.preventDefault (); est-ce que cela empêche le clic de l’étiquette de vérifier le bouton radio.

Une meilleure solution serait d’append simplement une vérification rapide “est cochée” comme suit:

 $("label").click(function(e){ var rbtn = $(this).find("input"); if(rbtn.is(':checked')){ **All the code you want to have happen on click** } )}; 

Mon problème est un peu différent, comme evt.stopPropagation();evt.preventDefault(); ne fonctionne pas pour moi, j’ajoute juste return false; finalement, ça marche.

 $("#addressDiv").on("click", ".goEditAddress", function(event) { alert("halo"); return false; }); 

Dans mon cas, le problème était que l’événement de clic se trouvait dans une fonction et que la fonction était exécutée deux fois . Chaque exécution de la fonction crée un nouvel événement de clic. – facepalm

après avoir déplacé l’événement click en dehors de la fonction, tout a fonctionné comme prévu! 🙂

La meilleure réponse est cachée dans les commentaires:

vous devriez réellement vous lier au change même sur le bouton radio, car le texte d’une étiquette est cliquable – ils ne cliquent pas toujours sur le bouton radio lui-même. – Chovy Dec 12 ’13 à 1:45

Ce violon montre que toutes les autres solutions – stopPropagation , stopImmediatePropagation , preventDefault , return false – ne changent rien ou détruisent la fonctionnalité de case à cocher / radio. Cela montre également qu’il s’agit d’un problème de JavaScript vanilla, pas d’un problème jQuery.

EDIT: Une autre solution que je viens de trouver dans un autre thread est de lier le onclick à l’entrée plutôt qu’à l’étiquette. Violon mis à jour

Essayez de mettre votre balise d’entrée en dehors de l’élément sortinggger, car la balise label émule click, vous aurez donc toujours plus d’un appel.