Javascript Can';t使用preventDefault()以编程方式检查单选按钮
我有一些元素(例如带有class.label的div),每个元素内部都有单选按钮。当用户单击此“标签”时,我通过编程将其中的收音机设置为选中状态。但是,如果我对click事件使用preventDefault(),则如果用户完全单击了收音机,则收音机不会被选中 请帮助我理解这种奇怪的行为我知道解决方案,我知道父元素上的preventDefault()为什么不允许检查收音机,但我想了解,为什么收音机上的单击事件可以不允许以编程方式设置其状态。您将看到,单击单选按钮将显示收音机已选中,但未选中Javascript Can';t使用preventDefault()以编程方式检查单选按钮,javascript,jquery,Javascript,Jquery,我有一些元素(例如带有class.label的div),每个元素内部都有单选按钮。当用户单击此“标签”时,我通过编程将其中的收音机设置为选中状态。但是,如果我对click事件使用preventDefault(),则如果用户完全单击了收音机,则收音机不会被选中 请帮助我理解这种奇怪的行为我知道解决方案,我知道父元素上的preventDefault()为什么不允许检查收音机,但我想了解,为什么收音机上的单击事件可以不允许以编程方式设置其状态。您将看到,单击单选按钮将显示收音机已选中,但未选中 $(
$(函数(){
$('.label')。在('click',函数(e)上{
var$radio=$(this.find(“:radio”)
log('before prevent','checked=${$radio.prop('checked')}`,'prevented=${e.isDefaultPrevented()}`);
e、 预防默认值();
if(!$(this).hasClass('checked')){
$('.checked').removeClass('checked');
$(this.addClass('checked');
}
$radio.prop('checked',true);
log('after prevent','checked=${$radio.prop('checked')}`,'prevented=${e.isDefaultPrevented()}`);
setTimeout(函数(){
log('after timeout','checked=${$radio.prop('checked')}`);
}, 500);
});
$(':radio')。在('click',函数(e)上{
log('click','prevented=${e.isDefaultPrevented()}');
});
});代码>
.label{
填充:10px;
边缘底部:10px;
边框:1px实心#000;
}
.标签{
背景颜色:绿色;
}
标签1
标签2
您只需添加e.stopPropagation()
即可再次返回选中的单选按钮的默认功能
其行为是,您的收音机
是div的子对象
,您的单击
侦听器基于父对象div
,当您preventDefault
时,子对象也会继承预防
检查
如果在一个元素上按下按钮并在另一个元素上释放,则事件将在包含这两个元素的最特定的祖先元素上触发
对父元素使用preventDefault()可以防止触发原始事件,但不会停止传播。理解层次结构和事件传播是至关重要的
您的代码片段中有部分解决方案。如果您注释掉了那一行,代码就会正常工作,正如您所期望的那样。
但是如果你使用
e.stopPropagation();
它也起作用
为了避免重复web上已有的信息,我在这里找到了一个非常类似的例子(),它可以帮助您更好地理解事件传播和冒泡
您还可以在这里找到更好的解释()
MDN文档也很少会给人留下深刻印象()。我如何看待这种情况(受以下启发):
上,它被处理。事件侦听器调用preventDefault
方法,设置内部cancelled
标志<代码>获取类“.checked”并再次将收音机设置为选中,现在以编程方式进行您是否有任何理由需要使用
e.preventDefault()
?默认情况下,
不是可单击的元素,因此它上没有与本机单击事件相关联的操作。顺便说一句,请使用语义。标签应该是标签
@Terry我可以删除e.preventDefault(),但当我遇到这种情况时,我决定找出为什么我不能通过编程检查收音机,如果它上的click事件设置为preventDefault()@QuentinVeron我简化了这段代码,事实上结构更复杂,可能重复的仍然不起作用。单击单选按钮不会检查它?我认为,您必须添加额外的单击处理程序到内置StopRopagation()的收音机中,并通过编程方式单击标签。但是,正如我在问题中所说,我知道解决方案,我想了解行为。谢谢你,我想,第一链接的答案澄清了我的情况。我已经更新了我的问题