【前端入门】事件模型深入:事件的传播与代理

105 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第18天,点击查看活动详情

上回分享了事件绑定监听函数的三种办法~ 发现事件发生后,在子元素和父元素之间存在事件的传播,我们今天来看看事件传播的三种阶段,和对应的事件代理!

事件的传播

一个事件发生后,会在子元素和父元素之间传播(propagation)

分成三个阶段:

  • 第一阶段:从window对象传导到目标节点(上层传到底层),称为“捕获阶段”(capture phase);即事件从<div><p>传播时,触发<div>click事件
  • 第二阶段:在目标节点上触发,称为“目标阶段”(target phase);即事件从<div>到达<p>时,触发<p>click事件
  • 第三阶段:从目标节点传导回window对象(从底层传回上层),称为“冒泡阶段”(bubbling phase);即事件从<p>传回<div>时,再次触发<div>click事件

事件的代理

事件的代理(delegation):由于事件会在冒泡阶段向上传播到父节点,因此可以把子节点的监听函数定义在父节点上,由父节点的监听函数统一处理多个子元素的事件

举例:

var ul = document.querySelector('ul');

ul.addEventListener('click', function (event) {
  if (event.target.tagName.toLowerCase() === 'li') {
    // some code
  }
});

上面代码中,click事件的监听函数定义在<ul>节点,但是实际上,它处理的是子节点<li>click事件。

好处:只要定义一个监听函数,就能处理多个子节点的事件,而不用在每个<li>节点上定义监听函数。而且以后再添加子节点,监听函数依然有效~~

不再传播(Stop Propagation):如果希望事件到某个节点为止,不再传播,可以使用事件对象的stopPropagation方法

例如:

// 事件传播到 p 元素后,就不再向下传播了
p.addEventListener('click', function (event) {
  event.stopPropagation();
}, true);

// 事件冒泡到 p 元素后,就不再向上冒泡了
p.addEventListener('click', function (event) {
  event.stopPropagation();
}, false);

上面代码中,stopPropagation方法分别在捕获阶段和冒泡阶段,阻止了事件的传播

取消事件:如果想要彻底取消该事件,不再触发后面所有click的监听函数,可以使用stopImmediatePropagation方法

例如:

p.addEventListener('click', function (event) {
  event.stopImmediatePropagation();
  console.log(1);
});

p.addEventListener('click', function(event) {
  // 不会被触发
  console.log(2);
});

//`stopImmediatePropagation`方法可以彻底取消这个事件
//使得后面绑定的所有`click`监听函数都不再触发
//最终,只会输出1,不会输出2

写在最后

以上习题&笔记从大佬们的论坛学习而来,特感谢大佬们的知识分享~ (学习技术知识,果然要看大佬们的技术博客,大家有好的推荐也欢迎指引我这个小白哈,感恩!)

附上学习链接,感谢这些大佬出题和解答:wangdoc.com/javascript/…