JS篇:事件流

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

参考博客

参考博客

一. DOM事件流

事件流图

1. 事件流过程

  • 元素事件响应在DOM树中是从顶层的Window开始“流向”目标元素(),然后又从目标元素“流向”顶层的Window。
  • 因为Window对象是直接面向用户的,那么用户触发一个事件,如点击事件,肯定是用window对象开始的,所以自然就是先捕获后冒泡

2.阶段

  1. 捕获阶段
    • 捕获阶段是指事件响应从最外层的Window开始,逐级向内层前进,直到具体事件目标元素。在捕获阶段,不会处理响应元素注册的冒泡事件。
  2. 目标阶段
    • 目标阶段指触发事件的最底层的元素,如上图中的。
  3. 冒泡阶段
    • 冒泡阶段与捕获阶段相反,事件的响应是从最底层开始一层一层往外传递到最外层的Window。

二. 设置事件冒泡和事件捕获

  • element.addEventListener(type, listener, useCapture)
    // type:监听事件类型的字符串
    // listener:事件监听回调函数,即事件触发后要处理的函数
    // useCapture: 默认值false,表示事件冒泡;设为true时,表示事件捕获
    复制代码
  • <div id="div1">
         <p>我是最外层的div</p>
         <div id="div2">
               <p>我是中间层的div</p>
               <div id="div3">
                   <p>我是最内层的div</p>
               </div>
         </div>
    </div>
    复制代码
  1. 冒泡

  • 将第三个参数设置为false
    复制代码
  1. 捕获

  • var a = document.getElementById("div1");
    var b = document.getElementById("div2");
    var c = document.getElementById("div3");
         a.addEventListener(
           "click",
           () => {
             alert("我是最外层的div");
           },
           true
         );
         b.addEventListener(
           "click",
           () => {
             alert("我是中间层的div");
           },
           true
         );
         c.addEventListener(
           "click",
           () => {
             alert("我是最内层的div");
           },
           true
         );
    复制代码

三. 事件冒泡(event bubbling)

1. 概念

  • 微软提出了名为事件冒泡(event bubbling)的事件流,由内向外响应

2. 阻止事件冒泡

1. 给子元素设置.stopPropagation()
  • // 给子元素设置.stopPropagation()
    function click3(e) {
            alert("我是最内层的div");
            var e = event || window.event;
            event.stopPropagation();
    }
    复制代码
  • event.stopPropagation()则只阻止事件往上冒泡,不阻止事件本身

2. event.target==event.currentTarget,让触发事件的元素等于绑定事件的元素,也可以阻止事件冒泡;
  • // 注意,如果采用这种方法阻止事件冒泡,必须所有属于冒泡影响范围内的元素都采用这个方法
    function click1() {
            var e = event || window.event;
            if (e.target == e.currentTarget) {
                alert("我是最外层的div");
            }
    }
    function click2() {
            var e = event || window.event;
            if (e.target == e.currentTarget) {
              alert("我是中间层的div");
            }
    }
    function click3() {
            var e = event || window.event;
            if (e.target == e.currentTarget) {
              alert("我是最内层的div");
            }
    }
    复制代码

四. 事件捕获(event capturing)

1. 概念

  • 网景提出了名为事件捕获(event capturing)的事件流,由外向内响应

五. 事件代理

1. 概念
  • 事件代理就是利用事件冒泡或事件捕获的机制把一系列的内层元素事件绑定到外层元素
2. 作用,减少监听器数量,去除重复笨重的代码
  • <ul id="item-list">
    	<li>item1</li>
    	<li>item2</li>
    	<li>item3</li>
    	<li>item4</li>
    </ul>
    复制代码
  • var items = document.getElementById('item-list');
    
    //事件捕获实现事件代理
    items.addEventListener('click', (e) => {console.log(e.target.innerHTML)}, true);
    
    //事件冒泡实现事件代理
    items.addEventListener('click', (e) => {console.log(e.target.innerHTML)}, false);
    
    复制代码
  • 通过事件代理实现点击对应li打印对应信息

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享