Обработчик события щелчка jQuery вызывается дважды для флажка
У меня проблема со следующим кодом на странице ASPX:
<script type="text/javascript">
$(document).ready(function() {
$('.test').click(function() {
alert("click")
})
});
</script>
<asp:CheckBox runat="server" Text="Checkbox XYZ" CssClass="test" ID="cb1" />
В браузере (FF3.5 / IE8) у меня следующая проблема:
- если я нажимаю флажок (маленький квадрат), он работает как положено
- если я щелкну по тексту флажка ("Checkbox XYZ"), то событие щелчка запускается дважды, и предупреждение отображается дважды.
Я предполагаю, что это связано с тем, как флажок отображается в HTML, например:
<span class="test">
<input id="ctl00_c1_cb1" type="checkbox" name="ctl00$c1$cb1" checked="checked"/>
<label for="ctl00_c1_cb1">Checkbox XYZ</label>
</span>
Как правильно настроить обработчик события click, чтобы он не вызывался дважды?
11 ответов
Хорошо прочитав мой вопрос еще раз, я нашел способ, как решить его.
Просто добавьте "input" в селектор jQuery:
<script type="text/javascript">
$(document).ready(function() {
$('.test input').click(function() {
alert("click")
})
});
</script>
Я только что испытал то же самое, но не уверен, что пузыри событий вызывают мою проблему. У меня есть пользовательский элемент управления дерева, и когда элемент открыт, я использую $(id).click()
прикрепить обработчик ко всем элементам определенного вида.
Я подозреваю, что это означает, что существующие элементы в других местах, в которых уже есть событие, могут затем добавить его снова. Я обнаружил, что снятие привязки со всего, а затем повторное связывание решило мою проблему, таким образом:
$('img.load_expand').unbind("click").click(function()
{
// handler
});
Я думаю, это потому, что <label>
с for
атрибут вызывает событие клика <input type="radio">
или же <input type="checkbox">
элемент, связанный с при нажатии.
Итак, в вашем коде jQuery вы устанавливаете обработчик события click для обоих <label>
и <input>
внутри <span class="test">
, При нажатии на <label>
, обработчик события щелчка, который вы настроили для метки, будет выполнен, затем обработчик события щелчка, настроенный на <input>
выполнится, когда метка вызовет событие нажатия на <input>
,
$(document).ready(function() {
$('.test').click(function(event) {
event.stopImmediatePropagation();
alert("Click");
})
}
);
Я смог заставить свой код работать, остановив распространение событий. Это не повлияло на изменение статуса чекбокса.
Решено: это для работы с Firefox 3.6.12 и IE8.
$(function(){
$("form input:checkbox").unbind("click")
.click(function(){
val = $(this).val();
alert(val);
})
}
Хитрость заключается в unbind("click").
прежде чем связать это с .click(fn)
; это отключит одно и то же событие, чтобы выстрелить дважды.
Обратите внимание, что событие "изменение" не будет обманутым при первом включении флажка. Поэтому вместо этого я использую "щелчок".
То, что вы видите, - это пузыри событий. Событие click сначала обрабатывается меткой, а затем передается флажку. Вы получаете одно предупреждение для каждого. Чтобы предотвратить появление событий, вам нужно вернуть false в ваш обработчик кликов.
$(document).ready(function() {
$('.test').click(function() {
alert("Click");
return false;
})
});
Однако, хотя это предотвращает возникновение событий, оно также имеет нежелательный побочный эффект, заключающийся в предотвращении изменения состояния флажка. Так что вам нужно обойти это.
Я столкнулся с той же проблемой с событием щелчка и нашел эту статью. По сути, если у вас есть несколько готовых к работе с документами функций jQuery внутри <body></body>
теги, вы можете получить несколько событий. Исправление, конечно, состоит в том, чтобы не делать этого, или отсоединять событие click и перепривязывать его, как отмечено выше. Иногда, с несколькими библиотеками javascript, может быть трудно избежать нескольких document.ready(), поэтому отмена привязки - хороший обходной путь.
<code>
$('#my-div-id').unbind("click").click(function()
{
alert('only click once!');
}
</code>
Я знаю, что вопрос сейчас закрыт, но я столкнулся с той же проблемой и хочу добавить найденное решение, которое может пригодиться в будущем для подобных проблем.
Когда вы добавляете код ASP, как:
<asp:CheckBox runat="server" Text="Checkbox XYZ" CssClass="test" ID="cb1" />
проблема в том, что <asp:CheckBox ...>
это не элемент управления html, это просто что-то ASP, созданное из извращенного ума какого-то придуманного психа, поэтому браузер получит что-то еще.
Браузер получит что-то вроде:
<span class="test">
<input id="garbageforYourId_cb1" type="checkbox" name="garbage$moregarbage$cb1"/>
<label for="evenMoreGarbage_cb1">Checkbox XYZ</label>
</span>
Одно из многих возможных решений:
Браузер получает промежуток, который содержит поле ввода и метку для него с вашим текстом. Поэтому мое решение для этого было бы что-то вроде:
$('.test > :checkbox').click(function() {
if ($(this).attr("checked")) {
alert("checked!!!");
} else {
alert("non checked!!!");
}
});
Что там произошло? Этот селектор $('.test > :checkbox')
означает: найдите элементы с классом "test" и принесите любой флажок, который он содержит.
У меня была такая же проблема с селектором. И в конечном итоге использовать
off()
функция.
$('body').off('click').on('click', '<your selector>', function(){
// Your code
});
Функция запускается дважды. Один раз изнутри, а затем снова вызывается изнутри. Просто добавьте оператор возврата в конце.
<script type="text/javascript">
$(document).ready(function() {
$('.test').click(function() {
alert("click");
return false;
})
});
</script>
<asp:CheckBox runat="server" Text="Checkbox XYZ" CssClass="test" ID="cb1" />
Это отлично сработало для меня.