为什么在父元素上单击“禁用”复选框preventDefault()? [英] Why does preventDefault() on a parent element's click 'disable' a checkbox?

查看:456
本文介绍了为什么在父元素上单击“禁用”复选框preventDefault()?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近遇到这种情况(这里简化)。只需用一个元素包装一个复选框,并对其单击事件应用preventDefault(),复选框变为不可选。



请参阅这个小提琴,但这里有一个剪辑: / p>

 < div> 
< input type =checkbox/>
< / div>

/ *包装器可以是任何元素(任何祖先元素都可以工作)* /
$('div')。on('click',function(e){
e.preventDefault();
});


/ *取消注释使复选框再次工作
$('input')。on('click',function(e){
e.stopPagagation ();
});
* /

这种行为发生在Chrome和FF,所以我认为这是故意的。



为什么已经在复选框中触发的点击事件不会导致复选框被切换?祖先上的 preventDefault 似乎应该与子复选框的行为无关。看起来好像,为了发生复选框更改,点击事件需要自由地泡到文档根。



这是怎么回事?

解决方案


对祖先的preventDefault似乎应该与子复选框的行为无关。


不,不是真的。事件气泡和所有处理程序(包括祖先上的那些)可能会影响它。


看起来好像,发生时,点击事件需要自由地一直冒泡到文档根。


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



您可能想读取DOM规范中的体系结构注释事件流默认操作和可取消事件

$ b $


  1. b $ b
  2. 检查

  3. 事件在文档根上分派

  4. (不在IE中):捕获阶段,您的处理程序没有任何反应

  5. 该事件到达 ;输入>

  6. ...并开始冒泡

  7. < div& / code>,它被处理。您的事件监听器调用 preventDefault 方法,并设置内部标志


  8. 由于事件已取消,因此不应发生默认操作,并且复选框重置为之前的状态。

如果您取消注释代码的第二部分,则步骤6+看起来不一样:


  1. 事件在< input> 上处理。您的监听器调用 stopPropagation 方法

  2. ...这导致跳过冒泡阶段。

  3. 未阻止默认操作,并且该复选框仍处于选中状态。


I encountered this situation recently (simplified here). Simply wrap a checkbox with an element and apply preventDefault() on it's click event and the checkbox becomes uncheckable.

See this fiddle, but here's a snip:

<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();
});
*/

The behavior occurs in Chrome and FF, so I assume it is intentional.

Why does the click event, which has already been triggered on the checkbox itself not result in the checkbox getting toggled? 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.

What's going on here?

解决方案

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

No, not really. The event bubbles, and all handlers (including the ones on ancestors) may affect it.

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

Not exactly. It doesn't need to arrive at the document root, but it must not have been default-prevented.

You might want to read the architecture notes in the DOM spec on event flow, default actions and cancelable events.

So what does happen step-by-step?

  1. You click on the checkbox
  2. It gets checked
  3. The event is dispatched on the document root
  4. (Not in IE): capture phase, nothing happens with your handlers
  5. The event arrives at the <input>
  6. …and begins to bubble
  7. On the <div>, it is handled. Your event listener calls the preventDefault method, setting an internal cancelled flag.
  8. It bubbles on, but nothing happens any more.
  9. Since the event was cancelled, the default action should not occur and the checkbox is reset to its previous state.

If you uncomment the second part of your code, steps 6+ look different:

  1. The event is handled on the <input>. Your listener calls the stopPropagation method
  2. …which leads to skipping the bubbling phase. (The div-listener will never be called)
  3. The default action was not prevented, and the checkbox stays checked.

这篇关于为什么在父元素上单击“禁用”复选框preventDefault()?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆