我使用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>
这种行为有什么解决方案吗?
答案 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说明了所有其他解决方案 - stopPropagation
,stopImmediatePropagation
,preventDefault
,return 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 次。