jqueryclick在单击标签时触发两次

jqueryclick在单击标签时触发两次,jquery,Jquery,我正在使用jQuery创建自定义单选按钮,但遇到了一个问题。 单击与收音机相关联的标签时,单击事件会触发两次,如果我只单击收音机本身,它工作正常(实际上,我单击的不是收音机,而是包装整个输入和标签的div)。代码如下: HTML: <div id="box"> <asp:RadioButtonList ID="RadioButtonList1" runat="server"> <asp:ListItem>RADIO1</as

我正在使用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>

无线电1
无线电2
无线电3
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>

$(函数(){
$(“#框”).find('input:radio')。每个(函数(i){
var输入=$(此);
//使用输入的id获取关联的标签
var label=$('label[for='+input.attr('id')+']');
//将输入+标签包装在一个div中
$(“”).insertBefore(输入).append(标签,输入);
var wrapperDiv=input.parent();
//使用“共享名称”属性查找此集合中的所有输入
var allInputs=$('input[name='+input.attr('name')+']);
//对于不支持标签上的:hover伪类的浏览器是必需的
标签悬停(
函数(){
$(this.addClass('hover');
},函数(){
$(this.removeClass('hover checkedHover');
});
//绑定自定义事件、触发它、绑定单击、聚焦、模糊事件
wrapperDiv.bind('updateState',函数(){
如果($(此)[0]。子项[1]。已选中){
所有输入。每个(函数(){
var curDiv=$('div>label[for='+$(this.attr('id')+']')).parent();
curDiv.removeClass(“自定义无线电检查”);
curDiv.addClass(“自定义无线电”);
});
$(this).toggleClass('custom-radio custom radio checked');
}
否则{
$(this.removeClass('custom-radio-checked-checked-hover-checked-focus');
}
})
.trigger('updateState'))
.click(函数(){console.log('click');})
.focus(函数(){
label.addClass('focus');
}).blur(函数(){
label.removeClass('focus checkedFocus');
});
}); 
});
是否有解决此问题的方法?

尝试添加:

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

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

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


祝您好运

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

$('input').click();
而不是

$('label').click();

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

如果您试图使用外部容器作为单击元素,也可以让事件自然冒泡,并在单击处理程序中测试所需的元素。如果您试图为表单设置唯一的单击区域样式,则此场景非常有用

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

我的复选框
$('#outer')。在('click',函数(e)上{
//这将触发#外部、标签和输入
如果(e.target.tagName==“输入”){
//只对输入感兴趣
console.log(this);
}
});

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

evt.stopPropagation();
evt.preventDefault();
但不起作用。但是添加以下内容:

evt.stopImmediatePropagation();

解决了问题!:)

我通常使用这个Syntax

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

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

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

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

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

在我的例子中,问题是我在一个函数中有一个单击事件,函数执行了两次,…函数的每次执行都会创建一个新的单击事件。-facepalm-


将click事件移到函数外部后,一切正常!:)

最佳答案隐藏在注释中:


您实际上应该绑定到
change
,即使是在单选按钮上,因为 标签的文本是可点击的——它们并不总是点击收音机 按钮本身-2013年12月12日1:45

这说明了所有其他解决方案——
stopPropagation
stoppimediatepropagation
preventDefault
return false
——要么什么也不更改,要么破坏复选框/无线电功能。它还说明这是一个普通的JavaScript问题,而不是jQuery问题

编辑:
我刚刚找到的另一个工作解决方案是将
onclick
绑定到输入,而不是标签。

我也遇到了同样的问题,因为我将我的收音机嵌套在标签中,像这样将处理程序连接到radio\u div。移除嵌套的标签修复了这个问题

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

添加到现有社区

我尝试添加解决方案

evt.stopPropagation();
evt.preventDefault();
但是没有起作用

加入

evt.stopImmediatePropagation();

解决了问题!:)

标签触发要选中的收音机/复选框

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

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

单击带有for=“some id”属性的标签会触发新的单击,但前提是目标存在并且是一个输入。我无法用e.preventDefault()或类似的东西完美地解决它,所以我
<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
    })
;