事件捕获、事件冒泡、事件委托【实践】

实践后加深的理解

一:事件流

对下事件流程图的理解

在这里插入图片描述

二:事件委托

事件委托原理
  • 大量同类型事件时,可以利用事件流的传递过程,将事件响应逻辑绑定在所有事件目标共同的祖先节点上,同时使用事件对象.target可以获取具体的事件目标节点进而获取事件目标的内容。
事件委托优点
  • 由于事件处理逻辑绑定在祖先节点而不是各个事件目标上,那么只需在祖先节点注册一次事件即可,而不用管子节点有多少个,或者子节点的动态添加。

实践过程

一:事件捕获和事件冒泡

测试代码如下
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>事件流</title>
    <style type="text/css">
        #outer{
    
    width: 150px;height: 150px;background-color: red;}
        #inner{
    
    width: 80px;height: 80px;background-color: green;}
    </style>
</head>
<body>
<div id="outer">outer box
    <div id="inner">inner box</div>
</div>

<script type="text/javascript">
    let inner = document.getElementById('inner');
    let outer = document.getElementById("outer");
    let body = document.getElementsByTagName("body")[0];
    let nodeArr = [inner,outer,body,document,window];
    let tipsArr = ["inner","outer","body","document","window"];
    nodeArr.forEach((ele,index)=>{
    
    
        ele.addEventListener('click',(e)=>{
    
    
            console.log(`${
      
      tipsArr[index]} click 捕获`);
        },true);
	    ele.addEventListener('click',(e)=>{
    
    
	         console.log(`${
      
      tipsArr[index]} click 冒泡`);
	    },false);
    });
</script>
</body>
</html>
运行结果(点击inner区域)

在这里插入图片描述

小细节:目标对象事件的捕获与冒泡与捕获事件/冒泡事件的执行顺序有关【测试如下】
  • 调整捕获/冒泡事件注册的顺序
// ...
   nodeArr.forEach((ele, index)=> {
    
    
   // 先为节点注册冒泡事件
        ele.addEventListener('click', (e)=> {
    
    
            console.log(`${
      
      tipsArr[index]} click 冒泡`);
        }, false);
        ele.addEventListener('click', (e)=> {
    
    
            console.log(`${
      
      tipsArr[index]} click 捕获`);
        }, true);
    });
  • 运行结果(点击inner区域,也即目标对象事件为inner的捕获与冒泡)
    在这里插入图片描述
捕获/冒泡拦截
  • 事件注册代码,添加事件拦截(如下例拦截冒泡)
// ...
    nodeArr.forEach((ele, index)=> {
    
    
        ele.addEventListener('click', (e)=> {
    
    
            console.log(`${
      
      tipsArr[index]} click 捕获`);
        }, true);
        ele.addEventListener('click', (e)=> {
    
    
            console.log(`${
      
      tipsArr[index]} click 冒泡`);
            e.stopPropagation();// 拦截冒泡
        }, false);
    });
  • 运行结果
    在这里插入图片描述

二:事件委托(代理)

测试代码如下
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>事件委托</title>
    <style>
        ul{
    
    
            float: left;
        }
    </style>
</head>
<body>
<ul>
    <li><button>one</button></li>
    <li><button>two</button></li>
    <li><button>three</button></li>
    <li><button>four</button></li>
    <li><button>five</button></li>
</ul>
<script>
    let ul = document.getElementsByTagName('ul')[0];
    ul.addEventListener('click', (e)=> {
    
    
        let btn = e.target;
        console.log(btn.textContent);
    }, true);// 这里使用捕获、冒泡均可
    function addLi(text){
    
    
        let li = document.createElement('li');
        let btn = document.createElement('button');
        btn.textContent = text;
        li.appendChild(btn);
        ul.appendChild(li);
    }
</script>
</body>
</html>
运行结果

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/jw2268136570/article/details/105272809