JS-事件冒泡捕获

wujiawen 发布于

事件冒泡、捕获

1
2
3
4
<!-- 例子 -->
<div id="outer">
<p id="inner">Click me!</p>
</div>
  • 事件冒泡
    微软提出了名为事件冒泡(event bubbling)的事件流

    事件冒泡可以形象地比喻为把一颗石头投入水中,泡泡会一直从水底冒出水面

    也就是说,事件会从最内层的元素开始发生,一直向上传播,直到document对象

    因此上面的例子在事件冒泡的概念下发生click事件的顺序应该是:
    p -> div -> body -> html -> document

  • 事件捕获
    网景提出另一种事件流名为事件捕获(event capturing)

    与事件冒泡相反,事件会从最外层开始发生,直到最具体的元素

    上面的例子在事件捕获的概念下发生click事件的顺序应该是:
    document -> html -> body -> div -> p

  • DOM事件
    DOM2级事件规定的事件流包含3个阶段

    事件捕获阶段、处于目标阶段、事件冒泡阶段

    首先发生的事件捕获为截获事件提供机会
    然后是实际的目标接收事件
    最后一个阶段是事件冒泡阶段,可以在这个阶段对事件做出响应

  • 正常添加的 onclick 事件都会经历 捕获、目标、冒泡 三个阶段

  • DOM2级事件方法
    DOM 2级事件定义了两方法:
    用于处理添加事件和删除事件的操作: 添加事件 addEventListener() 删除事件 removeEventListener()

 所有DOM节点中都包含这两个方法,并且他们都包含3个参数:
(1) 要处理的事件方式(例如:click,mouseover,dbclick…..)
(2)事件处理的函数,可以为匿名函数,也可以为命名函数(但如果需要删除事件,必须是命名函数)
(3)一个布尔值,代表是处于事件冒泡阶段处理还是事件捕获阶段
(true:表示在捕获阶段调用事件处理程序;false:表示在冒泡阶段调用事件处理程序)
第三个参数默认false

  • 通过addEventListener可以添加多个事件 会按添加顺序触发,且只能用removeEventListener来移除

  • 阻止捕获、冒泡
    event.stopPropagation()
    可阻止当前事件继续进行捕捉(capturing)及冒泡(bubbling)阶段的传递
    Vue框架中有 @click.capture.stop 可阻止事件传递

  • 应用实例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    <ul class="color_list">
    <li>red</li>
    <li>orange</li>
    <li>yellow</li>
    <li>green</li>
    <li>blue</li>
    <li>purple</li>
    </ul>
    <div class="box"></div>

    不必为每个li添加点击事件,可通过事件代理方法
    通过冒泡事件,在ul上添加click事件
    点击了 li 后会冒泡到 ul,此时就会触发绑定在 ul 上的点击事件
    再利用 target 找到事件实际发生的元素,就可以达到预期的效果

    1
    2
    3
    4
    5
    6
    7
    8
    // 伪代码
    function colorChange(e) {
    var e = e || window.event //兼容性的处理
    if(e.target.nodeName.toLowerCase() === "li") {
    box.innerHTML="该颜色为 " + e.target.innerHTML
    }
    }
    color_list.addEventListener("click", colorChange, false)