请考虑以下示例代码:
<span>
<input type="checkbox">
</span>
$('span').click(function(e) {
e.preventDefault();
$(':checkbox')[0].checked = true;
});
据我所知,这应该发生:
preventDefault()
应该阻止浏览器的默认行为检查复选框,即使事件处理程序附加在DOM层次结构的上方也是如此。这部分工作正常。.checked = true
应该有效,我相信它应该独立于浏览器对我已取消的事件的默认操作。这部分似乎有些错误,好像preventDefault()
正在影响它 - 删除preventDefault()
并按预期工作。该复选框始终未选中的实际原因是什么?
我在Chrome 33和Firefox 27上测试过,所以这似乎不是浏览器错误。
这个问题主要是由于好奇心扩展我的DOM /事件模型知识。我不想要解决方法,而是想知道为什么这个例子失败了。
答案 0 :(得分:4)
鉴于你的HTML:
<span>
<input type="checkbox">
</span>
和你的代码:
$('span').click(function(e) {
e.preventDefault();
$(':checkbox')[0].checked = true;
});
事件冒泡是你的问题。
点击checkbox
后,点击事件会传播到span
。 e.preventDefault()
是从checkbox
传播的事件对象的调用。
因此preventDefault()
针对checkbox
本身执行,阻止对其进行检查。
checkbox
的点击事件通过preventDefault
被“取消”,它将一直保持取消,直到事件流程完成。 (有关详细信息,请参阅答案底部)
如果您在某个范围内应用了某些样式,则会发现点击checkbox
代码的工作方式符合预期,但点击checkbox
本身会因上述问题而复制您的问题。
DEMO - 原始小提琴+风格。点击span
即可,checkbox
不是
根据MDN documentation on preventDefault():
在事件流程的任何阶段调用
preventDefault
取消 事件,意味着通常采取的任何默认操作 由于事件的实施不会发生。
DOM Level 2 Spec还注明:
如果事件可取消,则使用
preventDefault
方法 表示该事件将被取消,表示任何默认操作 由于事件通常采取的执行不会 发生。 在事件流的任何阶段,如果是preventDefault方法 被称为事件被取消。
示例5中的DOM Level 3 Events Spec注释:
与
click
元素上的<input type="checkbox">
事件相关联的默认操作会切换该元素的checked
IDL属性值。如果取消click
事件的默认操作,则该值将恢复为以前的状态。
答案 1 :(得分:3)
在setTimeout
中包含部分代码可以解决问题,正如您在此处所见http://jsfiddle.net/y7C77/
$('span').click(function(e) {
e.preventDefault();
setTimeout(function () {
$('input').prop('checked', true);
}, 1);
});
preventDefault()
取消默认操作,我认为即使您手动执行浏览器操作,它也可以取消它(在这种情况下:更改checked
属性)。
答案 2 :(得分:2)
这是我感觉到的预期行为,因为当你说event.preventDefault()时,你指示浏览器在这个事件中不对它做任何操作。因此,即使在您明确选中复选框的语句之后,浏览器也不会对其执行任何操作。 当我按如下方式更改事件时,我们可以看到差异:
$('span').click(function(e) {
e.preventDefault();
//$(':checkbox')[0].checked = true;
setTimeout(function(){$(':checkbox')[0].checked = true;});
});
使用超时我们正在更改事件外的checked属性,因此会检查它。
答案 3 :(得分:1)
您必须preventDefault
同时click
和mouseup
并设置选中mouseup
尝试:
$('span').click(function(e) {
e.preventDefault();
}).mouseup(function(e){
e.preventDefault();
$(':checkbox')[0].checked = true;
});