为何点击子元素会触发父元素事件?示例代码事件冒泡疑问解析
关于事件冒泡的两个常见问题解答
1. 为什么点击子元素时父元素的事件会被触发?
这是浏览器自带的**事件冒泡(Event Bubbling)**机制在起作用。简单来说,当你点击一个DOM元素时,浏览器会先触发这个元素自身的事件处理函数,随后事件会沿着DOM树从内到外逐层向上“冒泡”,依次触发它的父元素、祖父元素……的同名事件。
举个直观的例子:如果有这样的结构 <div class="parent"><button class="child">点我</button></div>,给父div和子button都绑定了click事件,那点击button时,button的click事件会先执行,紧接着父div的click事件也会被触发——这就是事件冒泡导致的。
2. 示例代码中点击DIV时FORM的事件为何会被触发?
先看你提供的示例代码:
<!DOCTYPE HTML> <html> <head> <meta charset="utf-8"> </head> <body> <style> body * { margin: 10px; border: 1px solid blue; } </style> <form onclick="event.stopPropagation();alert('form')">FORM <div>DIV <p onclick="event.stopPropagation();alert('p')">P</p> </div> </form> </body> </html>
这里的核心误区是对event.stopPropagation()作用的理解,咱们拆解下:
- 当你点击DIV时,DIV本身没有绑定任何click事件处理函数,所以事件会直接向上冒泡到它的父元素FORM。
- 你在FORM的
onclick里调用的event.stopPropagation(),作用是阻止事件继续向上传播到FORM的父元素(比如body、html),而不是阻止事件触发FORM自己的事件。事件已经到达FORM了,所以alert('form')自然会执行。 - 反观点击P元素的情况:P的
onclick里调用了event.stopPropagation(),这会直接阻止事件从P冒泡到DIV和FORM,所以点击P时只会弹出p,不会触发上层元素的事件——这才是用stopPropagation()阻止事件冒泡到父元素的正确场景。
如果想让点击DIV时不触发FORM的事件,你需要给DIV也绑定一个onclick事件,在里面调用event.stopPropagation(),修改后的代码如下:
<div onclick="event.stopPropagation();">DIV <p onclick="event.stopPropagation();alert('p')">P</p> </div>
这样点击DIV时,事件在DIV这一层就被阻止冒泡,不会传到FORM了。
内容的提问来源于stack exchange,提问作者Chinmoy Samanta
相关产品推荐
相关产品推荐

