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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8238599/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 10:14:13  来源:igfitidea点击:

jQuery Click fires twice when clicking on label

jquery

提问by tone

I am using jQuery to create custom radio buttons and i have a problem. When clicking on the label that associated with the radio the click events fires twice, if i click only on the radio itself it's working fine (well actually it's not the radio i am clicking but the div that wraps the whole input and label). Here is the code:

我正在使用 jQuery 创建自定义单选按钮,但遇到了问题。当点击与收音机关联的标签时,点击事件会触发两次,如果我只点击收音机本身,它工作正常(实际上我点击的不是收音机,而是包装整个输入和标签的 div)。这是代码:

The HTML:

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:

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>

Is there any solution for this behaviour?

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

回答by N3da

I tried adding the solution above by adding:

我尝试通过添加以下内容来添加上面的解决方案:

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

but didn't work. However adding this:

但没有用。但是添加这个:

evt.stopImmediatePropagation();

solved the problem! :)

解决了问题!:)

回答by Jordan

Try adding:

尝试添加:

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

to the .bind() or .click(), whichever you're seeing. Also, add the parameter evtto the function, like function(evt) {...

到 .bind() 或 .click(),无论您看到哪个。另外,将参数添加evt到函数中,例如function(evt) {...

回答by dougmacknz

Bind the click event to the input rather than the label. When the label is clicked - the event will still occur because, as Dustin mentioned, a click on the label triggers a click on the input. This will allow the label to hold its normal functionality.

将点击事件绑定到输入而不是标签。当标签被点击时 - 该事件仍然会发生,因为正如达斯汀提到的,点击标签会触发点击输入。这将允许标签保持其正常功能。

$('input').click();

Instead of

代替

$('label').click();

回答by tobius

If you're trying to use an outer container as a click element you can also let the events bubble naturally and test for the expected element in your click handler. This scenario is useful if you're trying to style a unique click zone for a form.

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

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

回答by Dustin

To fix this the easy way, remove the "for" attribute on the label. A click on the label will also trigger a click on the associated element. (which in your case is firing your click event twice.)

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

Good luck

祝你好运

回答by Dalibor

I usually use this synthax

我通常使用这个合成器

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

instead of

代替

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

回答by WoodrowShigeru

Best answer is hidden inside comments:

最佳答案隐藏在评论中:

you should actually bind to changeeven on the radio button since the text of a label is clickable -- they don't always click the radio button itself. – chovyDec 12 '13 at 1:45

您实际上应该绑定到change甚至在单选按钮上,因为标签的文本是可点击的——他们并不总是点击单选按钮本身。– chovy 2013 年12 月 12 日 1:45

This fiddleillustrates that all the other solutions – stopPropagation, stopImmediatePropagation, preventDefault, return false– either change nothing or destroy the checkbox/radio functionality). It also illustrates that this is a vanilla JavaScript problem, not a jQuery problem.

这个小提琴说明了所有其他解决方案 – stopPropagation, stopImmediatePropagation, preventDefault, return false– 要么什么都不改变,要么破坏复选框/收音机功能)。它还说明这是一个普通的 JavaScript 问题,而不是一个 jQuery 问题。

EDIT:Another working solution that I just found in another threadis to bind the onclickto the input rather than the label. Updated fiddle.

编辑:我刚刚在另一个线程中找到的另一个工作解决方案是将 the 绑定onclick到输入而不是标签。更新了小提琴

回答by Janki Moradiya

I have tried by adding solution.

我已经尝试通过添加解决方案。

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

but didn't work.

但没有用。

By adding

通过添加

evt.stopImmediatePropagation();

solved the problem! :)

解决了问题!:)

回答by GMsoF

My problem is a bit different, as the evt.stopPropagation();evt.preventDefault();doesn't work for me, I just add return false;in the end, then it works.

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

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

回答by FalcoB

In my case the problem was that i had the click event in a functionand the function was executed twice.... every execution of the function creates a new click event. -facepalm-

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

after moving the click event outside the function, everything worked as expected! :)

将点击事件移到函数外后,一切都按预期进行!:)