我最近遇到过这种情况(这里简化)。只需用一个元素包装一个复选框,并在它的click事件上应用preventDefault(),然后该复选框将被取消选中。
请参阅this fiddle,但这是一个剪辑:
<div>
<input type="checkbox"/>
</div>
/* Wrapper could be any element (and any ancestor element will work) */
$('div').on('click', function(e){
e.preventDefault();
});
/* Uncomment to make the checkbox work again
$('input').on('click', function(e){
e.stopPropagation();
});
*/
行为发生在Chrome和FF中,因此我认为这是故意的。
为什么已经在复选框上触发的click事件不会导致复选框被切换?祖先的preventDefault
似乎应该与子复选框的行为无关。似乎,为了发生复选框更改,click事件需要一直自由地冒泡到文档根目录。
这里发生了什么?
答案 0 :(得分:11)
对祖先的preventDefault似乎应该与子复选框的行为无关。
不,不是真的。事件起泡,所有处理程序(包括祖先的处理程序)都可能会影响它。
似乎,为了发生复选框更改,click事件需要一直自由地冒泡到文档根目录。
不完全是。它不需要到达文档根目录,但它不能被默认阻止。
您可能希望在event flow,default actions and cancelable events上阅读DOM规范中的体系结构说明。
那么一步一步发生什么呢?
<input>
<div>
上,它会被处理。您的事件侦听器调用preventDefault
方法,设置内部cancelled
标记。如果您取消注释代码的第二部分,则步骤6+看起来不同:
<input>
处理。您的监听器调用stopPropagation
方法答案 1 :(得分:5)
preventDefault
可防止触发浏览器的默认操作。更改复选框的选中状态或跟随锚点的href
,提交表单等是默认操作。 preventDefault
在允许事件传播的同时阻止它们。
这与事件传播不同(您可以 - 正如您所指出的那样 - 停靠stopPropagation
)。在调用浏览器的默认行为之前,事件将在整个侦听器层次结构中传播(除非被阻止)。