单击标签时,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
jQuery Click fires twice when clicking on label
提问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 evt
to 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
change
even 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 onclick
to the input rather than the label. Updated fiddle.
回答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! :)
将点击事件移到函数外后,一切都按预期进行!:)