DOM事件的传播机制

DOM事件的传播机制是指当一个事件在DOM树中触发时,它是如何在各个元素之间传播的。DOM事件传播机制分为三个阶段:捕获阶段、目标阶段和冒泡阶段。此外,还有一种常用的技术称为事件委托,它能够简化事件处理程序的绑定和管理。本文将详细介绍这些概念,并提供相应的代码示例。

事件与事件流

在介绍事件传播机制之前,我们先来了解一下什么是事件和事件流。在DOM中,事件是指用户与页面交互时发生的动作,比如点击、鼠标移动等。而事件流则是指这些事件在DOM树中传播的路径。

每次用户与一个网页进行交互,例如点击链接,按下一个按键或者移动鼠标时,就会触发一个事件。我们的程序可以检测这些事件,然后对此作出响应。从而形成一种交互。

这样可以使我们的页面变得更加的有意思,而不仅仅像以前一样只能进行浏览。

JavaScript 中采用一个叫做事件监听器的东西来监听事件是否发生。这个事件监听器类似于一个通知,当事件发生时,事件监听器会让我们知道,然后程序就可以做出相应的响应。

通过这种方式,就可以避免让程序不断地去检查事件是否发生,让程序在等待事件发生的同时,可以继续做其他的任务。

标准 DOM 事件流

DOM事件流是指在DOM树中,事件从最外层的节点开始传播,逐级向下,直到达到目标节点,然后再从目标节点向上传播到最外层的节点。

DOM事件流分为三个阶段:捕获阶段、目标阶段和冒泡阶段。

  1. 捕获阶段:事件从最外层的节点开始传播,逐级向下,直到达到目标节点。在捕获阶段中,事件会依次触发每个经过的节点上绑定的捕获型事件处理函数。
  2. 目标阶段:事件达到目标节点后,在目标节点上触发绑定的事件处理函数。在这个阶段中,只会触发目标节点上绑定的事件处理函数。
  3. 冒泡阶段:事件从目标节点开始向上传播,逐级向上,直到达到最外层的节点。在冒泡阶段中,事件会依次触发每个经过的节点上绑定的冒泡型事件处理函数。

在实际应用中,默认情况下大部分DOM事件都是按照冒泡方式进行传播。但是也可以通过调用addEventListener方法时传入第三个参数为true来将其设置为捕获方式进行传播。

总结起来,DOM事件流就是指从最外层的节点开始传播,逐级向下到达目标节点,然后再从目标节点向上传播到最外层的节点的过程。这个过程分为捕获阶段、目标阶段和冒泡阶段。

下面是一个示例,演示了标准 DOM 事件流的传播顺序:

复制代码
html 复制代码
<div id="outer">
  <div id="inner">
    <button id="btn">点击我</button>
  </div>
</div>
复制代码
javascript 复制代码
const outer = document.getElementById('outer');
const inner = document.getElementById('inner');
const btn = document.getElementById('btn');

outer.addEventListener('click', function() {
  console.log('外层元素被点击');
}, true);

inner.addEventListener('click', function() {
  console.log('内层元素被点击');
}, true);

btn.addEventListener('click', function() {
  console.log('按钮被点击');
});

当我们点击按钮时,控制台会输出以下内容:

外层元素被点击 内层元素被点击 按钮被点击

可以看到,事件首先在捕获阶段从外层元素开始传播,然后到达目标元素,最后在冒泡阶段从目标元素向上冒泡。

事件冒泡流

事件冒泡是指在DOM树中,事件从目标元素开始向上冒泡传播的过程。也就是说,在冒泡阶段,事件会依次触发父级元素的相同类型事件处理程序。

下面是一个示例,演示了事件冒泡的过程:

复制代码
html 复制代码
<div id="outer">
  <div id="inner">
    <button id="btn">点击我</button>
  </div>
</div>
javascript 复制代码
const outer = document.getElementById('outer');
const inner = document.getElementById('inner');
const btn = document.getElementById('btn');

outer.addEventListener('click', function() {
  console.log('外层元素被点击');
});

inner.addEventListener('click', function() {
  console.log('内层元素被点击');
});

btn.addEventListener('click', function() {
  console.log('按钮被点击');
});

当我们点击按钮时,控制台会输出以下内容:

按钮被点击 内层元素被点击 外层元素被点击

可以看到,事件首先在目标元素上触发,然后在冒泡阶段依次触发父级元素的相同类型事件处理程序。

事件捕获流

事件捕获是指在DOM树中,事件从最外层的父级元素开始向下捕获传播的过程。也就是说,在捕获阶段,事件会依次触发父级元素的相同类型事件处理程序。

下面是一个示例,演示了事件捕获的过程:

复制代码
html 复制代码
<div id="outer">
  <div id="inner">
    <button id="btn">点击我</button>
  </div>
</div>
javascript 复制代码
const outer = document.getElementById('outer');
const inner = document.getElementById('inner');
const btn = document.getElementById('btn');

outer.addEventListener('click', function() {
  console.log('外层元素被点击');
}, true);

inner.addEventListener('click', function() {
  console.log('内层元素被点击');
}, true);

btn.addEventListener('click', function() {
  console.log('按钮被点击');
});

当我们点击按钮时,控制台会输出以下内容:

外层元素被点击 内层元素被点击 按钮被点击

可以看到,事件首先在捕获阶段依次触发父级元素的相同类型事件处理程序,然后到达目标元素。

事件委托流

事件委托是一种常用的技术,它利用了事件冒泡的特性。通过在父级元素上绑定一个事件处理程序,可以监听子级元素触发的事件。这样一来,无论子级元素是已经存在的还是动态生成的,都可以通过父级元素来管理它们的事件。

下面是一个示例,演示了事件委托的过程:

复制代码
html 复制代码
<ul id="list">
  <li>列表项1</li>
  <li>列表项2</li>
  <li>列表项3</li>
</ul>
复制代码
javascript 复制代码
const list = document.getElementById('list');

list.addEventListener('click', function(event) {
  if (event.target.tagName === 'LI') {
    console.log('列表项被点击');
    console.log('触发事件的目标元素是:', event.target);
  }
});

当我们点击任意一个列表项时,控制台会输出以下内容:

列表项被点击 触发事件的目标元素是: <li>列表项1</li>

可以看到,通过在父级元素上绑定点击事件处理程序,我们可以捕获到子级元素触发的点击事件,并且可以获取到触发事件的目标元素。这样一来,无论我们添加或删除列表项,只需要在父级元素上绑定一个事件处理程序即可。

总结

通过以上介绍,我们了解了DOM事件传播机制的三个阶段:捕获阶段、目标阶段和冒泡阶段。此外,我们还学习了如何利用事件委托来简化事件处理程序的绑定和管理。掌握这些概念和技巧,能够帮助我们更好地处理和管理DOM中的各种交互事件。

相关推荐
cs_dn_Jie3 分钟前
钉钉 H5 微应用 手机端调试
前端·javascript·vue.js·vue·钉钉
开心工作室_kaic37 分钟前
ssm068海鲜自助餐厅系统+vue(论文+源码)_kaic
前端·javascript·vue.js
有梦想的刺儿1 小时前
webWorker基本用法
前端·javascript·vue.js
清灵xmf2 小时前
TypeScript 类型进阶指南
javascript·typescript·泛型·t·infer
小白学大数据2 小时前
JavaScript重定向对网络爬虫的影响及处理
开发语言·javascript·数据库·爬虫
qq_390161772 小时前
防抖函数--应用场景及示例
前端·javascript
334554322 小时前
element动态表头合并表格
开发语言·javascript·ecmascript
John.liu_Test2 小时前
js下载excel示例demo
前端·javascript·excel
PleaSure乐事3 小时前
【React.js】AntDesignPro左侧菜单栏栏目名称不显示的解决方案
前端·javascript·react.js·前端框架·webstorm·antdesignpro
哟哟耶耶3 小时前
js-将JavaScript对象或值转换为JSON字符串 JSON.stringify(this.SelectDataListCourse)
前端·javascript·json