我正在使用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>
Run Code Online (Sandbox Code Playgroud)
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>
Run Code Online (Sandbox Code Playgroud)
这种行为有什么解决方案吗?
N3d*_*3da 180
我尝试添加以下解决方案:
evt.stopPropagation();
evt.preventDefault();
Run Code Online (Sandbox Code Playgroud)
但没有奏效.但是添加这个:
evt.stopImmediatePropagation();
Run Code Online (Sandbox Code Playgroud)
解决了这个问题!:)
Jor*_*dan 123
尝试添加:
evt.stopPropagation();
evt.preventDefault();
Run Code Online (Sandbox Code Playgroud)
到.bind()或.click(),无论你看到了什么.另外,将参数添加evt
到函数中,例如function(evt) {...
dou*_*knz 66
将click事件绑定到输入而不是标签.单击标签时 - 事件仍将发生,因为正如Dustin所说,标签上的单击会触发对输入的单击.这将允许标签保持其正常功能.
$('input').click();
Run Code Online (Sandbox Code Playgroud)
代替
$('label').click();
Run Code Online (Sandbox Code Playgroud)
tob*_*ius 11
如果您尝试使用外部容器作为单击元素,您还可以让事件自然地冒泡并测试单击处理程序中的预期元素.如果您尝试为表单设置唯一的单击区域样式,则此方案很有用.
<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>
Run Code Online (Sandbox Code Playgroud)
小智 7
我尝试过添加解决方案。
evt.stopPropagation();
evt.preventDefault();
Run Code Online (Sandbox Code Playgroud)
但没有用。
通过增加
evt.stopImmediatePropagation();
Run Code Online (Sandbox Code Playgroud)
解决了问题!:)
我通常会使用这种合成胶
.off('click').on('click', function () { console.log('click'); })
Run Code Online (Sandbox Code Playgroud)
代替
.click(function () { console.log('click'); })
Run Code Online (Sandbox Code Playgroud)
最佳答案隐藏在评论中:
您实际上应该绑定到
change
甚至在单选按钮上,因为标签的文本是可点击的——他们并不总是点击单选按钮本身。– chovy 2013 年12 月 12 日 1:45
这个小提琴说明了所有其他解决方案 – stopPropagation
, stopImmediatePropagation
, preventDefault
, return false
– 要么什么都不改变,要么破坏复选框/收音机功能)。它还说明这是一个普通的 JavaScript 问题,而不是一个 jQuery 问题。
编辑:
我刚刚在另一个线程中找到的另一个工作解决方案是将 the 绑定onclick
到输入而不是标签。更新了小提琴。