Обработчик события jQuery click вызывается дважды для флажка - PullRequest
20 голосов
/ 08 октября 2009

У меня проблема со следующим кодом на странице 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, чтобы он не вызывался дважды?

Ответы [ 10 ]

57 голосов
/ 04 декабря 2009

Я только что испытал то же самое, но не уверен, что пузыри событий вызывают мою проблему. У меня есть пользовательский элемент управления деревом, и когда элемент открывается, я использую $(id).click(), чтобы прикрепить обработчик ко всем элементам определенного вида.

Я подозреваю, что это означает, что существующие объекты в других местах, в которых уже есть событие, могут затем добавить его снова. Я обнаружил, что снятие привязки со всего, а затем повторное связывание решило мою проблему, таким образом:

$('img.load_expand').unbind("click").click(function()
{
  // handler
});
20 голосов
/ 08 октября 2009

Я думаю, это потому, что <label> с атрибутом for вызывает событие click для элемента <input type="radio"> или <input type="checkbox">, который ассоциируется при нажатии.

Таким образом, в вашем коде jQuery вы устанавливаете обработчик событий щелчка для <label> и <input> внутри <span class="test">. При нажатии на <label> будет выполнен обработчик события щелчка, настроенный для метки, затем обработчик события щелчка, настроенный на <input>, будет выполнен, когда метка вызовет событие щелчка на <input>.

14 голосов
/ 26 ноября 2009
$(document).ready(function() {
    $('.test').click(function(event) {
                    event.stopImmediatePropagation();
                    alert("Click");
                    })
                 }
              );

Я смог заставить свой код работать, остановив событие Распространение. Это не повлияло на изменение статуса флажка.

8 голосов
/ 08 октября 2009

Хорошо, прочитав мой вопрос еще раз, я нашел способ, как решить его.

Просто добавьте «input» в селектор jQuery:

<script type="text/javascript">
$(document).ready(function() {
        $('.test input').click(function() {
                alert("click")
        })
});
</script>
3 голосов
/ 06 января 2013

Просто используйте .mouseup вместо .click

2 голосов
/ 27 ноября 2010

Решено: это для работы с Firefox 3.6.12 и IE8.

$(function(){
        $("form input:checkbox").unbind("click")
        .click(function(){
            val = $(this).val();
            alert(val);
        })
    }

Хитрость в том, чтобы unbind("click")., прежде чем связать его с .click(fn); это отключит одно и то же событие, чтобы выстрелить дважды.

Обратите внимание, что флажок «изменение» не сработает при первом включении. Поэтому вместо этого я использую «щелчок».

2 голосов
/ 08 октября 2009

То, что вы видите, - это пузыри событий. Событие click сначала обрабатывается меткой, а затем передается флажку. Вы получаете одно предупреждение для каждого. Чтобы предотвратить появление событий, вам нужно вернуть false в обработчике кликов.

$(document).ready(function() {
        $('.test').click(function() {
                alert("Click");
                return false;
        })
});

Однако, хотя это предотвращает всплытие событий, оно также имеет нежелательный побочный эффект - предотвращение изменения состояния флажка. Так что вам нужно обойти это.

1 голос
/ 31 декабря 2013

Я знаю, что вопрос сейчас закрыт, но я только что столкнулся с той же проблемой и хочу добавить найденное решение, которое может пригодиться в будущем для подобных проблем.

При добавлении 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» и установите любой флажок, который он содержит.

1 голос
/ 19 сентября 2011

Я столкнулся с той же проблемой с событием щелчка и нашел эту статью. По сути, если у вас есть несколько готовых к работе с документами функций jQuery внутри <body></body> теги, вы можете получить несколько событий. Исправление, конечно, состоит в том, чтобы не делать этого, или отсоединять событие click и перепривязывать его, как отмечено выше. Иногда, с несколькими библиотеками javascript, может быть трудно избежать нескольких document.ready (), поэтому отмена привязки - хороший обходной путь.

<code>
$('#my-div-id').unbind("click").click(function()
  {
    alert('only click once!');
  }
</code>
0 голосов
/ 02 сентября 2013

Функция запускается дважды. Один раз изнутри, а затем он снова вызывается изнутри. Просто добавьте оператор возврата в конце.

<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" />

Это отлично сработало для меня.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...