1.理解事件冒泡和事件捕获
在JS中,我们管事件发生的顺序叫“事件流”,当触发某个事件时,会发生一系列的连锁反应
<div class="grandpa">
我是爷爷div
<p class="son">
我是儿子p
<a class="grandson" href="#">我是孙子a</a>
</p>
</div>
如果给每个标签都绑定一个事件,当点击<a>标签时,会发现绑定在<div>和<p>标签上的事件也会被触发,这是为什么呢?为了解答这个问题,微软和网景公司提出了两种不同的概念:事件捕获 与 事件冒泡
(1)事件捕获:由微软公司提出来的,事件从文档根节点(Document 对象)流向目标节点,途中会经过目标节点的各个父级节点,并在这些节点上触发捕获事件,直至到达事件的目标节点
(2)事件冒泡:由网景公司提出,与事件捕获相反,事件会从目标节点流向文档根节点,途中会经过目标节点的各个父级节点,并在这些节点上触发捕获事件,直至到达文档的根节点。整个过程就像水中的气泡一样,从水底向上运动
Tips:上面提到的目标节点指的是触发事件的节点
后来,W3C 为了统一标准,采用了一个折中的方式,即将事件捕获与事件冒泡合并,也就是现在的“先捕获后冒泡”,如下图所示:
2.事件捕获(event capturing)
在事件捕获阶段,事件会从 DOM 树的最外层开始,依次经过目标节点的各个父节点,并触发父节点上的事件,直至到达事件的目标节点。以上图中的代码为例,如果单击其中的<a>标签,
则该事件将通过document -> div -> p -> a的顺序传递到<a>标签。
拓展:
element.addEventListener(event, function, useCapture)
addEventListener方法用来为一个特定的元素绑定一个事件处理函数,有三个参数,分别是"没有on的事件类型"、"事件处理函数"、"控制事件阶段",第三个参数是boolean类型,默认是false,表示在事件冒泡的阶段调用事件处理函数,像上面代码中传入true,就表示在事件捕获的阶段调用事件处理函数。
3.事件冒泡(event bubbling)
事件冒泡正好与事件捕获相反,事件冒泡是从目标节点开始,沿父节点依次向上,并触发父节点上的事件,直至文档根节点,就像水底的气泡一样,会一直向上。
4.阻止事件捕获和冒泡
了解了事件捕获和事件冒泡后会发现,这个特性并不友好,例如我们在某个节点上绑定了事件,本想在点击时触发这个事件,结果由于事件冒泡,这个节点的事件被它的子元素给触发了。我们要如何阻止这样的事情发生呢?
JS中提供了stopPropagation() 方法来阻止事件捕获和事件冒泡的发生,语法格式如下:
event.stopPropagation();
注意:stopPropagation()会阻止事件捕获和事件冒泡,但是无法阻止标签的默认行为,例如点击链接任然可以打开对应网页。
此外,可以使用stopImmediatePropagation()方法来阻止同一节点的同一事件的其它事件处理程序,例如:为某个节点定义了多个点击事件,当事件触发时,这些事件会按定义顺序依次执行,如果其中一个事件处理程序中使用了 stopImmediatePropagation() 方法,那么剩下的事件处理程序将不再执行。
语法格式如下:
event.stopImmediatePropagation();
示例:
文章来源地址https://www.toymoban.com/news/detail-485616.html
5.阻止默认操作
某些事件具有与之关联的默认操作,例如:当单击某个链接时,会自动跳转到指定的页面,当单击提交按钮时,会将数据提交到服务器等。如果不想这样的默认操作发生,可以使用 preventDefault() 方法来阻止,其语法格式如下:
event.preventDefault();
示例:
注意:IE9 及以下的版本不支持 preventDefault() 方法,对于 IE9 及以下的浏览器可以使用 event.returnValue = false;文章来源:https://www.toymoban.com/news/detail-485616.html
到了这里,关于事件冒泡和捕获的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!