javascript - 为什么父元素上的 preventDefault() 单击 'disable' 复选框?

标签 javascript html checkbox preventdefault stoppropagation

最近遇到这种情况(这里简化)。简单地用一个元素包裹一个复选框并在它的点击事件上应用 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 中,因此我认为这是故意的。

为什么已经在复选框上触发的点击事件不会导致复选框被切换?祖先上的 preventDefault 似乎应该与子复选框的行为无关。似乎,要发生复选框更改,单击事件需要一直自由冒泡到文档根目录。

这是怎么回事?

最佳答案

The preventDefault on the ancestor seems like it ought to be irrelevant to the child checkbox's behavior.

不,不是真的。事件冒泡,所有处理程序(包括祖先上的处理程序)都可能影响它。

It seems as if, for the checkbox change to occur, the click event needs to bubble freely all the way to the document root.

不完全是。它不需要到达文档根目录,但它不能被默认阻止。

您可能想阅读 event flow 上 DOM 规范中的体系结构说明, default actions and cancelable events .

那么逐步发生了什么?

  1. 您点击复选框
  2. 它被检查
  3. 事件在文档根上调度​​
  4. (不在 IE 中):capture phase ,你的处理程序没有任何反应
  5. 事件到达 <input>
  6. ……开始冒泡
  7. <div> 上,它被处理了。您的事件监听器调用 preventDefault方法,设置内部 cancelled旗帜。
  8. 它继续冒泡,但什么也没有发生。
  9. 由于事件已取消,默认操作不应发生,复选框将重置为之前的状态。

如果您取消注释代码的第二部分,第 6 步以上看起来会有所不同:

  1. 事件在 <input> 上处理.您的听众调用 stopPropagation方法
  2. …这会导致跳过冒泡阶段。 (永远不会调用 div-listener)
  3. 未阻止默认操作,复选框保持选中状态。

关于javascript - 为什么父元素上的 preventDefault() 单击 'disable' 复选框?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15767083/

相关文章:

javascript - KnockoutJS 未在复选框列表中选择选中的值

javascript - 我如何使用 3 个复选框/单选按钮作为选项在 javascript 中创建提示?

javascript - 如何与youtube.com上的YouTube播放器(而非iFrame API)互动?

拖动时 HTML5 拖放更改光标(不使用 UI)

DBgrid 中的 Delphi 复选框

javascript - react 组件中的背景图像

javascript - 使用向上和向下箭头进行自动完成搜索

javascript - 为什么我的 JavaScript 函数没有触发?

Javascript - 从选中的复选框中检索输入值并对其进行处理

javascript - 在 JQuery 中区分此代码段中的 2 个复选框