javascript - 无法使用 preventDefault() 以编程方式检查单选按钮
问题描述
我有一些元素(例如带有类 .label 的 div),其中每个元素都带有单选按钮。当用户单击此“标签”时,我以编程方式将其中的单选设置为选中状态。但是,如果我将 preventDefault() 用于单击事件,则如果用户完全单击了收音机,则不会选择收音机。
请帮助我理解这种奇怪的行为。我知道解决方案,我知道为什么 parent 元素上的 preventDefault() 不允许检查收音机,但我想了解,为什么收音机上的 click 事件不允许以编程方式设置其状态。您会看到单击单选按钮会说已选中单选,但事实并非如此。
$(function () {
$('.label').on('click', function(e) {
var $radio = $(this).find(':radio')
console.log('before prevent', `checked=${$radio.prop('checked')}`, `prevented=${e.isDefaultPrevented()}`);
e.preventDefault();
if (!$(this).hasClass('checked')) {
$('.checked').removeClass('checked');
$(this).addClass('checked');
}
$radio.prop('checked', true);
console.log('after prevent', `checked=${$radio.prop('checked')}`, `prevented=${e.isDefaultPrevented()}`);
setTimeout(function () {
console.log('after timeout', `checked=${$radio.prop('checked')}`);
}, 500);
});
$(':radio').on('click', function (e) {
console.log('click', `prevented=${e.isDefaultPrevented()}`);
});
});
.label {
padding: 10px;
margin-bottom: 10px;
border: 1px solid #000;
}
.label.checked {
background-color: green;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="label">
Label 1 <input type="radio" name="radio" value="1">
</div>
<div class="label">
Label 2 <input type="radio" name="radio" value="2">
</div>
更新。我如何看待这种情况:
- 用户点击收音机
- 首先在收音机上触发事件并将输入设置为选中。
- 然后事件冒泡并触发
.label
- 调用 preventDefault() 会设置一个内部
cancelled
标志。 div
现在以编程方式再次将“.checked”类和收音机设置为已检查。- 事件冒泡,但不再发生任何事情。
- 由于事件已取消,因此不应发生默认操作,并且复选框将重置为之前的状态。
我对吗?
解决方案
我如何看待这种情况(受https://stackoverflow.com/a/15767580/11357125启发):
- 你点击收音机
- 它被检查
- 该事件在文档根目录上调度
- 捕获阶段,您的处理程序没有任何反应
- 活动到达
<input>
- ……开始冒泡
- 在 上
<div>
,它被处理。事件监听器调用该preventDefault
方法,设置一个内部cancelled
标志。现在以编程方式再次<div>
将“.checked”类和收音机设置为已检查。 - 事件冒泡,但不再发生任何事情。
- 由于事件已取消,因此不应发生默认操作,并且即使在以编程方式选中复选框后,复选框也会重置为之前的状态。
推荐阅读
- python - 在python中删除TFIDF结果的同义词
- javascript - 让我的日期选择器传递他的价值的麻烦
- javascript - How to update an element using .textContent
- c# - 这是对控制台应用程序进行单元测试的正确方法吗?
- java - 不使用 String 方法 - contains、indexOf、lastIndexOf 判断子字符串是否在字符串中
- sql - 使用资源 DLL 的 SQL Server CLR 函数 - 示例或建议?
- r - 每 3 行求和
- python - Pandas:在列之间交换行
- arrays - 从 JSON 中获取元素并对其进行切片
- mysql - 无法创建 MySql 触发器