【发布时间】:2019-04-13 21:25:17
【问题描述】:
我有一些元素(例如带有 .label 类的 div),其中每个元素都带有单选按钮。当用户单击此“标签”时,我以编程方式将其中的单选设置为选中状态。但是,如果我使用 preventDefault() 作为点击事件,如果用户完全点击了收音机,则不会选择收音机。
请帮助我理解这种奇怪的行为。 我知道解决方案,我知道为什么父元素上的 preventDefault() 不允许检查收音机,但我想了解,为什么收音机上的点击事件不允许以编程方式设置其状态。您会看到单击单选按钮会说已选中单选,但事实并非如此。
$(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' 并将单选设置为再次选中,现在以编程方式。 - 事件冒泡,但没有任何反应。
- 由于事件已取消,因此不应发生默认操作,复选框将重置为之前的状态。
我说的对吗?
【问题讨论】:
-
你有什么理由需要使用
e.preventDefault()吗?<div>默认情况下不是可点击元素,因此无论如何都没有与原生点击事件相关的操作/操作。 -
顺便说一句,使用语义。标签应该是
label。 -
@Terry 我可以删除 e.preventDefault(),但是当我遇到这种情况时,我决定找出,如果单击事件设置为 preventDefault(),为什么我不能以编程方式检查收音机
-
@QuentinVeron 这段代码我简化了,其实结构更复杂
标签: javascript jquery