JQuery Нажмите два раза при нажатии на метку

Я использую jQuery для создания пользовательских переключателей, и у меня есть проблема. При нажатии на метку, связанную с радио, события щелчка срабатывают дважды, если я нажимаю только на радио, он работает нормально (ну, собственно, это не радио, которое я нажимаю, а div, который обертывает весь ввод и метку). Вот код:

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

Есть ли какое-либо решение для этого поведения?

Ответ 1

Попробуйте добавить:

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

в .bind() или .click(), в зависимости от того, что вы видите. Кроме того, добавьте параметр evt к функции, например function(evt) {...

Ответ 2

Я попытался добавить решение выше, добавив:

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

но не работает. Однако добавив следующее:

evt.stopImmediatePropagation();

решил проблему!:)

Ответ 3

Привязать событие клика к входу, а не к метке. Когда нажимается метка - событие все равно будет происходить, потому что, как отметил Дастин, щелчок по метке вызывает щелчок на вкладке. Это позволит ярлыку поддерживать нормальную функциональность.

$('input').click();

Вместо

$('label').click();

Ответ 4

Если вы пытаетесь использовать внешний контейнер в качестве элемента click, вы также можете позволить событиям пузырьки естественным образом и проверить ожидаемый элемент в вашем обработчике кликов. Этот сценарий полезен, если вы пытаетесь создать уникальную зону клика для формы.

<form>
<div id="outer">
    <label for="mycheckbox">My Checkbox</label>
    <input type="checkbox" name="mycheckbox" id="mycheckbox" value="on"/>
</div>
</form>
<script>
$('#outer').on('click', function(e){
    // this fires for #outer, label, and input
    if (e.target.tagName == 'INPUT'){
        // only interested in input
        console.log(this);
    }
});
</script>

Ответ 5

Чтобы устранить этот простой способ, удалите атрибут "для" на ярлыке. Щелчок на метке также вызовет щелчок по связанному элементу. (который в вашем случае дважды запускает событие click.)

Удачи.

Ответ 6

Лучший ответ скрыт внутри комментариев:

на самом деле вы должны связать change даже с переключателем, так как текст метки кликабелен - они не всегда нажимают сам переключатель. - Чови 12 декабря 13 в 1:45

Эта скрипка иллюстрирует, что все другие решения - stopPropagation, stopImmediatePropagation, preventDefault, return false - либо ничего не меняют, либо разрушают функциональные возможности флажка/радио). Это также показывает, что это ванильная проблема JavaScript, а не проблема jQuery.

РЕДАКТИРОВАТЬ: Еще одно рабочее решение, которое я только что нашел в другом потоке, заключается в onclick к вводу, а не к метке. Обновленная скрипка.

Ответ 7

Я обычно использую этот синтакс

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

вместо

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

Ответ 8

Проблема с e.preventDefault(); это останавливает щелчок ярлыка от проверки переключателя.

Лучшим решением было бы просто добавить проверку "проверено" так:

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

Ответ 9

Моя проблема немного отличается, так как evt.stopPropagation();evt.preventDefault(); не работает для меня, я просто добавляю return false; в конце, тогда он работает.

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

Ответ 10

В моем случае проблема состояла в том, что у меня было событие click в функции, и функция была выполнена дважды.... каждое выполнение функции создает новое событие click. -facepalm-

после перемещения события click за пределы функции все заработало как положено! :)

Ответ 11

Попробуйте поместить свой тег входа вне элемента триггера, потому что метка метки эмулирует клик, так что у вас будет всегда более одного вызова.

Ответ 12

У меня была такая же проблема, потому что я вложил свое радио в ярлык вот так с обработчиком, прикрепленным к radio_div. Удаление вложенной метки устранило проблему.

<div id="radio_div">
    <label>
       <input type="radio" class="community_radio" name="community_radio" value="existing">
           Add To Existing Community
    </label>
</div>

Ответ 13

Я попытался, добавив решение.

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

но не сработало.

Добавляя

evt.stopImmediatePropagation();

решил проблему! :)

Ответ 14

Метка вызывает радио/флажок для проверки.

if ($(event.target).is('label')){
    event.preventDefault();
}

Это препятствует особенно метке, чтобы вызвать это поведение.

Ответ 15

Просто хотел прослушивать здесь, я использую WooCombinator в WordPress WooCommerce, который использует ссылки, которые выглядят как кнопки для выбора вариантов, а не по умолчанию. Я хотел бы выполнить некоторый код JQuery на выбранных вариантах, и многие из ответов здесь не остановили эффект барботирования.

Комментарий Yoshyosh о попытке использовать mouseup вместо щелчка работает как шарм, я не могу поверить, что не думал об этом! Спасибо yoshyosh!