美文网首页
事件冒泡、事件捕获、事件代理

事件冒泡、事件捕获、事件代理

作者: 不退则进_笑 | 来源:发表于2020-10-22 14:26 被阅读0次

1,背景

  • 事件冒泡是微软提出
  • 事件捕获是网景公司提出
  • 都是为了解决页面中事件发生的顺序,但是他们的提出几乎相当于 2 种完全相反的概念

2,例子:

<div id="outer" onClick={()=>{}}>
    <p id="inner" onClick={()=>{}}>Click me!</p>
</div>

3,事件冒泡

  • 事件冒泡可以形象地比喻为把一颗石头投入水中,泡泡会一直从水底冒出水面。也就是说,事件会从最内层的元素开始发生,一直向上传播,直到 document 对象

  • 因此在事件冒泡的概念下在 p 元素上发生 click 事件的顺序应该是 p -> div -> body -> html -> document

4,事件捕获

  • 网景提出另一种事件流名为事件捕获(event capturing)。与事件冒泡相反,事件会从最外层开始发生,直到最具体的元素
  • 因此在事件捕获的概念下在 p 元素上发生 click 事件的顺序应该是 document -> html -> body -> div -> p

5,addEventListener 的第三个参数

  • 网景 和 微软 曾经的战争还是比较火热的,当时, 网景主张捕获方式,微软主张冒泡方式。后来 w3c 采用折中的方式,平息了战火,制定了统一的标准——先捕获再冒泡
  • addEventListener 的第三个参数就是为冒泡和捕获准备的
  • element.addEventListener(event, function, useCapture)
  • 第一个参数是需要绑定的事件
  • 第二个参数是触发事件后要执行的函数
  • 第三个参数默认值是 false,表示在事件冒泡阶段调用事件处理函数;如果参数为 true,则表示在事件捕获阶段调用处理函数。

6,冒泡的案例

<div id="s1">s1
    <div id="s2">s2</div>
</div>
<script>
    s1.addEventListener("click",function(e){
        console.log("s1 冒泡事件");
    },false);
    s2.addEventListener("click",function(e){
        console.log("s2 冒泡事件");
    },false);
</script>

// s2 冒泡事件
// s1 冒泡事件

7,捕获的案例

<div id="s1">s1
    <div id="s2">s2</div>
</div>
<script>
    s1.addEventListener("click",function(e){
        console.log("s1 捕获事件");
    },true);
    s2.addEventListener("click",function(e){
        console.log("s2 捕获事件");
    },true);
</script>

// s1 捕获事件
// s2 捕获事件

8,事件捕获和事件冒泡,一起存在

<div id="s1">s1
    <div id="s2">s2</div>
</div>
<script>
s1.addEventListener("click",function(e){
        console.log("s1 冒泡事件");
},false);
s2.addEventListener("click",function(e){
        console.log("s2 冒泡事件");
},false);

s1.addEventListener("click",function(e){
        console.log("s1 捕获事件");
},true);

s2.addEventListener("click",function(e){
        console.log("s2 捕获事件");
},true);
</script>

  • s1 捕获事件
  • s2 冒泡事件
  • s2 捕获事件
  • s1 冒泡事件
8.1 执行顺序
  • document 往 target 节点,捕获前进,遇到注册的捕获事件立即触发执行
  • 到达 target 节点,触发事件(对于 target 节点上,是先捕获还是先冒泡取决于捕获事件和冒泡事件的注册顺序,先注册先执行)
  • target 节点 往 document 方向,冒泡前进,遇到注册的冒泡事件立即触发
8.2 总结
  • 对于非 target 节点则先执行捕获在执行冒泡
  • 对于 target 节点则是先执行先注册的事件

8,选择冒泡还是捕获?

  • 对于事件代理来说,在事件捕获或者事件冒泡阶段处理并没有明显的优劣之分,但是由于事件冒泡的事件流模型被所有主流的浏览器兼容,从兼容性角度来说还是建议大家使用事件冒泡模型

9,IE 浏览器兼容

  • IE 浏览器对 addEventListener 兼容性并不算太好,只有 IE9 以上可以使用
  • 要兼容旧版本的 IE 浏览器,可以使用 IE 的 attachEvent 函数
  • object.attachEvent(event, function)
  • 两个参数与 addEventListener 相似,分别是事件和处理函数,默认是事件冒泡阶段调用处理函数,要注意的是,写事件名时候要加上"on"前缀("onload"、"onclick")等

10,事件代理(事件委托)

  • 事件委托的原理是 DOM 元素的事件冒泡,把里层所需要响应的事件绑定到外层

  • 使用“事件委托”时,并不是说把事件委托给的元素越靠近顶层就越好。事件冒泡的过程也需要耗时,越靠近顶层,事件的”事件传播链”越长,也就越耗时。如果 DOM 嵌套结构很深,事件冒泡通过大量祖先元素会导致性能损失。

  • 例子:

<ul id="myLinks">
      <li id="goSomewhere">Go somewhere</li>
      <li id="doSomething">Do something</li>
      <li id="sayHi">Say hi</li>
    </ul>
    <script>
      var item1 = document.getElementById('goSomewhere')
      var item2 = document.getElementById('doSomething')
      var item3 = document.getElementById('sayHi')

      item1.onclick = function () {
        location.href = 'http://www.baidu.com'
      }
      item2.onclick = function () {
        document.title = '事件委托'
      }
      item3.onclick = function () {
        alert('hi')
      }
    </script>

如果在一个复杂的 Web 应用程序中,对所有可单击的元素都采用这种方式,那么结果就会有数不 清的代码用于添加事件处理程序。此时,可以利用事件委托技术解决这个问题。使用事件委托,只需在 DOM 树中尽量最高的层次上添加一个事件处理程序,

  • 如下面的例子所示:
 <script>
      var allItems = document.getElementById('myLinks')
      allItems.addEventListener('click', function (event) {
        var target = event.target
        switch (target.id) {
          case 'doSomething':
            document.title = '事件委托'
            break
          case 'goSomewhere':
            location.href = 'http://www.baidu.com'
            break
          case 'sayHi':
            alert('hi')
            break
        }
      })
    </script>

相关文章

  • Javascript 事件代理、冒泡和捕获

    2019开工荒了两天,赶紧开始! 为什么写事件代理、冒泡、捕获,首先冒泡和捕获是js事件的核心基础,事件代理原理来...

  • 事件代理及常用的 HTML 事件

    之前总结了事件捕获和冒泡以及阻止事件传播,今天写一下事件代理方面的总结DOM 事件之捕获、冒泡:阻止事件传播: 事...

  • 事件冒泡、事件捕获、事件代理

    1,背景 事件冒泡是微软提出 事件捕获是网景公司提出 都是为了解决页面中事件发生的顺序,但是他们的提出几乎相当于 ...

  • 事件代理、事件冒泡、事件捕获

    Document div {width: 100px;height: 100px...

  • 2022-01-09 浏览器相关面试知识点

    一.详解浏览器事件捕获与冒泡 1. 事件委托/事件代理 捕获阶段-->目标阶段-->冒泡阶段 第三个参数为true...

  • zj9 事件

    事件模型、事件冒泡、事件捕获、事件代理、阻止默认事件、事件兼容等 题目1: DOM0 事件和DOM2级在事件监听使...

  • 事件冒泡、事件捕获、事件委托

    事件冒泡、事件捕获、事件委托

  • DOM事件

    DOM事件、事件冒泡、捕获、代理 1. 什么是事件 2. 常用的事件 onclick:当点击时操作 onchang...

  • DOM-BOM-EVENT(7)

    7.事件深入 #7.1.事件捕获 事件流分为事件冒泡和事件捕获两种,事件冒泡指事件从里往外传播,而事件捕获刚好相反...

  • 前端知识二

    事件委托(事件代理) 事件委托也可以叫事件代理,是事件冒泡与事件捕获的运用。 基本概念 一般来讲,会把一个或者一组...

网友评论

      本文标题:事件冒泡、事件捕获、事件代理

      本文链接:https://www.haomeiwen.com/subject/mznumktx.html