单击标签时,jQuery Click会触发两次

时间:2011-11-23 07:31:05

标签: 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'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>

这种行为有什么解决方案吗?

16 个答案:

答案 0 :(得分:172)

我尝试添加以下解决方案:

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

但没有奏效。但是添加这个:

evt.stopImmediatePropagation();
解决了这个问题! :)

答案 1 :(得分:120)

尝试添加:

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

到.bind()或.click(),无论你看到了什么。另外,将参数evt添加到函数中,例如function(evt) {...

答案 2 :(得分:59)

将click事件绑定到输入而不是标签。单击标签时 - 事件仍将发生,因为正如Dustin所说,标签上的单击会触发对输入的单击。这将允许标签保持其正常功能。

$('input').click();

而不是

$('label').click();

答案 3 :(得分:10)

如果您尝试使用外部容器作为单击元素,您还可以让事件自然起泡并测试单击处理程序中的预期元素。如果您尝试为表单设置唯一的单击区域,则此方案很有用。

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

答案 4 :(得分:8)

要轻松解决此问题,请删除标签上的“for”属性。单击标签也会触发相关元素的单击。 (在您的情况下,两次点击事件。)

祝你好运

答案 5 :(得分:3)

我通常使用这个synthax

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

而不是

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

答案 6 :(得分:3)

最佳答案隐藏在评论中:

  

你应该实际上绑定到change甚至是单选按钮   标签的文本是可点击的 - 它们并不总是单击收音机   按钮本身。 - chovy 2013年12月12日1:45

fiddle说明了所有其他解决方案 - stopPropagationstopImmediatePropagationpreventDefaultreturn false - 不做任何更改或破坏复选框/广播功能)。它还说明了这是一个普通的JavaScript问题,而不是jQuery问题。

编辑: 我刚刚发现in another thread的另一个工作解决方案是将onclick绑定到输入而不是标签。 Updated fiddle

答案 7 :(得分:1)

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**
  }
)};

答案 8 :(得分:1)

我的问题有点不同,因为evt.stopPropagation();evt.preventDefault();对我不起作用,我最后只添加return false;,然后就可以了。

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

答案 9 :(得分:1)

在我的情况下,问题是我在函数中有click事件并且函数执行了两次 ....每次执行该函数都会创建一个新函数点击事件。 - 捂脸 -

将click事件移到函数外部后,一切都按预期工作! :)

答案 10 :(得分:0)

尝试将输入标记放在触发元素之外,因为标签标记模拟了点击,因此您将始终有多个调用。

答案 11 :(得分:0)

我遇到了同样的问题,因为我已经将无线电广播像这样嵌套在标签内,并在radio_div上附加了处理程序。删除嵌套标签可解决此问题。

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

答案 12 :(得分:0)

我尝试添加解决方案。

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

但是没有用。

通过添加

evt.stopImmediatePropagation();

解决了问题! :)

答案 13 :(得分:0)

标签触发单选框/复选框被选中。

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

它特别防止标签触发此行为。

答案 14 :(得分:0)

单击具有 for =“ some-id” 属性的标签会触发新的点击,但前提是目标存在并且是输入。我不能不能用e.preventDefault()或类似的东西完美地解决它,所以我这样做是这样的:

例如,如果您具有这种结构,并且想要在单击.some-class

时发生事件
<div class="some-class">
    <input type=checkbox" id="the-input-id" />
    <label for="the-input-id">Label</label>
</div>

起作用的是:

$(document)
    .on('click', '.some-class', function(e) {
        if(
            $(e.target).is('label[for]')
            &&
            $('input#' + $(e.target).attr('for')).length
        ) {
            // This will trigger a new click so we are out of here
            return;
        }

        // else do your thing here, it will not get called twice
    })
;

答案 15 :(得分:-1)

$(document).on('click','.class',function() {
    alert('abc')
})

在我的情况下,它触发了 2 次,因为我包含了这个代码 2 次,例如 assets/js/test.js 2 次。