J'utilise jQuery pour créer des boutons radio personnalisés et j'ai un problème. Lorsque vous cliquez sur l'étiquette associée à la radio, les événements de clic se déclenchent deux fois, si je ne clique que sur la radio elle-même, cela fonctionne bien (en fait, ce n'est pas la radio sur laquelle je clique mais le div qui enveloppe toute l'entrée et l'étiquette). Voici le code:
Le HTML:
<div id="box">
<asp:RadioButtonList ID="RadioButtonList1" runat="server">
<asp:ListItem>RADIO1</asp:ListItem>
<asp:ListItem>RADIO2</asp:ListItem>
<asp:ListItem>RADIO3</asp:ListItem>
</asp:RadioButtonList>
</div>
jQuery:
<script type="text/javascript">
$(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
$('<div class="custom-radio"></div>').insertBefore(input).append(label, input);
var wrapperDiv = input.parent();
// find all inputs in this set using the shared name attribute
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, trigger 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');
}
})
.trigger('updateState')
.click(function () { console.log('click'); })
.focus(function () {
label.addClass('focus');
}).blur(function () {
label.removeClass('focus checkedFocus');
});
});
});
</script>
Y a-t-il une solution à ce comportement?
jQuery('input').prop('checked', true);
return false;
équivaut à `evt.stopPropagation (); evt.preventDefault (); ( dans jQuery )J'ai essayé d'ajouter la solution ci-dessus en ajoutant:
mais n'a pas fonctionné. Cependant en ajoutant ceci:
résolu le problème! :)
la source
evt.stopPropagation(); evt.preventDefault();
; 'tLiez l'événement de clic à l'entrée plutôt qu'à l'étiquette. Lorsque vous cliquez sur l'étiquette, l'événement se produira toujours car, comme Dustin l'a mentionné, un clic sur l'étiquette déclenche un clic sur l'entrée. Cela permettra à l'étiquette de conserver sa fonctionnalité normale.
Au lieu de
la source
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.label > input
configuration Bootstrapesque , c'est LA réponse, pas une réponse. L'ajout deevt.stopPropagation()
ouevt.preventDefault()
à votre code, bien qu'efficace, est un piratage à éviter lorsque la solution appropriée est beaucoup plus propre et plus efficace.Si vous essayez d'utiliser un conteneur externe comme é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 styliser une zone de clic unique pour un formulaire.
la source
if (e.target == e.currentTarget) {}
Pour résoudre ce problème facilement, supprimez l'attribut "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 deux fois votre événement de clic.)
Bonne chance
la source
J'utilise habituellement cette syntaxe
au lieu de
la source
La meilleure réponse est cachée dans les commentaires:
Ce violon montre que toutes les autres solutions -
stopPropagation
,stopImmediatePropagation
,preventDefault
,return false
- soit rien changer ou détruire la case à cocher / fonctionnalité radio). Cela montre également qu'il s'agit d'un problème JavaScript vanille, pas d'un problème jQuery.EDIT: Une autre solution de travail 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 .la source
J'ai essayé en ajoutant une solution.
mais n'a pas fonctionné.
En ajoutant
résolu le problème! :)
la source
Le problème avec e.preventDefault (); est-ce que cela empêche le clic d'étiquette de vérifier le bouton radio.
Une meilleure solution serait d'ajouter simplement une vérification rapide «est vérifié» comme ceci:
la source
Mon problème est un peu différent, car
evt.stopPropagation();evt.preventDefault();
cela ne fonctionne pas pour moi, j'ajoute simplementreturn false;
à la fin, puis cela fonctionne.la source
Dans mon cas, le problème était que j'avais l'événement de clic 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 de clic en dehors de la fonction, tout a fonctionné comme prévu! :)
la source
Essayez de placer votre balise d'entrée en dehors de l'élément déclencheur, car la balise d'étiquette émule le clic, vous aurez donc toujours plus d'un appel.
la source
J'ai eu le même problème parce que j'avais imbriqué ma radio dans l'étiquette comme celle-ci avec le gestionnaire attaché à radio_div. La suppression de l'étiquette imbriquée a résolu le problème.
la source
L'étiquette déclenche la case à cocher / radio à cocher.
Il empêche surtout l'étiquette de déclencher ce comportement.
la source
Le clic sur l'étiquette avec un attribut for = "some-id" déclenche un nouveau clic, mais uniquement si la cible existe et est une entrée. Je n'ai pas pu le résoudre parfaitement avec e.preventDefault () ou des trucs comme ça, alors je l'ai fait comme ceci:
Par exemple, si vous avez cette structure et souhaitez un événement en cliquant sur .some-class
Ce qui a fonctionné était:
la source