Używam jQuery do tworzenia niestandardowych przycisków opcji i mam problem. Po kliknięciu etykiety, która jest związana z radiem, zdarzenia kliknięcia są uruchamiane dwukrotnie, jeśli kliknę tylko na samo radio, działa dobrze (właściwie to nie radio, które klikam, ale div, który otacza całe wejście i etykietę). Oto kod:
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>
Czy jest jakieś rozwiązanie tego zachowania?
jQuery('input').prop('checked', true);
return false;
jest równoważne z `evt.stopPropagation (); evt.preventDefault (); ( w jQuery )Próbowałem dodać powyższe rozwiązanie dodając:
ale nie zadziałało. Jednak dodając to:
Rozwiązać problem! :)
źródło
evt.stopPropagation(); evt.preventDefault();
; 'tPowiąż zdarzenie kliknięcia z wejściem, a nie z etykietą. Po kliknięciu etykiety - zdarzenie będzie nadal występować, ponieważ, jak wspomniał Dustin, kliknięcie etykiety powoduje kliknięcie wejścia. Pozwoli to etykiecie zachować normalną funkcjonalność.
Zamiast
źródło
change
nawet z przyciskiem opcji, ponieważ tekst etykiety jest klikalny - nie zawsze klikają sam przycisk opcji.label > input
konfiguracji Bootstrapesque , jest to odpowiedź, a nie odpowiedź. Dodanieevt.stopPropagation()
lubevt.preventDefault()
do kodu, choć skuteczne, to hack, którego należy unikać, gdy właściwe rozwiązanie jest znacznie czystsze i wydajniejsze.Jeśli próbujesz użyć zewnętrznego kontenera jako elementu kliknięcia, możesz również pozwolić zdarzeniom w naturalny sposób bąbelkować i przetestować pod kątem oczekiwanego elementu w module obsługi kliknięcia. Ten scenariusz jest przydatny, jeśli próbujesz stylizować unikalną strefę kliknięcia dla formularza.
źródło
if (e.target == e.currentTarget) {}
Aby rozwiązać ten problem w łatwy sposób, usuń atrybut „for” z etykiety. Kliknięcie etykiety spowoduje również kliknięcie skojarzonego elementu. (co w Twoim przypadku powoduje dwukrotne uruchomienie zdarzenia kliknięcia).
Powodzenia
źródło
Zwykle używam tej składni
zamiast
źródło
Najlepsza odpowiedź jest ukryta w komentarzach:
To skrzypce ilustruje, że wszystkie inne rozwiązania -
stopPropagation
,stopImmediatePropagation
,preventDefault
,return false
- albo zmiana nic lub zniszczyć pole wyboru / funkcjonalność radia). Pokazuje również, że jest to zwykły problem JavaScript, a nie problem jQuery.EDYCJA: Innym działającym rozwiązaniem, które właśnie znalazłem w innym wątku, jest powiązanie pliku
onclick
danymi wejściowymi, a nie etykietą. Zaktualizowane skrzypce .źródło
Próbowałem, dodając rozwiązanie.
ale nie zadziałało.
Poprzez dodanie
Rozwiązać problem! :)
źródło
Problem z e.preventDefault (); czy powstrzymuje kliknięcie etykiety przed sprawdzeniem przycisku opcji.
Lepszym rozwiązaniem byłoby po prostu dodanie szybkiego sprawdzenia „jest zaznaczone” w następujący sposób:
źródło
Mój problem jest trochę inny, bo u
evt.stopPropagation();evt.preventDefault();
mnie nie działa, po prostureturn false;
na koniec dodaję i działa.źródło
W moim przypadku problem polegał na tym, że miałem zdarzenie click w funkcji i funkcja była wykonywana dwukrotnie ... każde wykonanie funkcji tworzy nowe zdarzenie kliknięcia. - facepalm -
po przeniesieniu zdarzenia click poza funkcję wszystko działało zgodnie z oczekiwaniami! :)
źródło
Spróbuj umieścić swój tag wejściowy poza elementem wyzwalającym, ponieważ tag etykiety emuluje kliknięcie, więc zawsze będziesz mieć więcej niż jedno wywołanie.
źródło
Miałem ten sam problem, ponieważ umieściłem moje radio wewnątrz etykiety w ten sposób z programem obsługi podłączonym do radio_div. Usunięcie zagnieżdżonej etykiety rozwiązało problem.
źródło
Etykieta wyzwala zaznaczenie radia / pola wyboru.
Zapobiega to, zwłaszcza etykiecie, aby wywołać to zachowanie.
źródło
Kliknięcie etykiety z atrybutem for = "some-id" wyzwala nowe kliknięcie, ale tylko wtedy, gdy cel istnieje i jest wejściem. Byłem nie stanie rozwiązać go doskonale z e.preventDefault () lub rzeczy tak więc zrobiłem to tak:
Na przykład, jeśli masz taką strukturę i chcesz zdarzenie po kliknięciu .some-class
Co zadziałało:
źródło