JS之事件委托

1.使用背景

当需要批量添加事件监听时,比如点击每个li都将变为字体变为红色。

目标效果如下:
在这里插入图片描述

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <ul id="list">
        <li>列表项</li>
        <li>列表项</li>
        <li>列表项</li>
        <li>列表项</li>
        <li>列表项</li>
        <li>列表项</li>
        <li>列表项</li>
        <li>列表项</li>
        <li>列表项</li>
        <li>列表项</li>
        <li>列表项</li>
        <li>列表项</li>
        <li>列表项</li>
        <li>列表项</li>
        <li>列表项</li>
        <li>列表项</li>
        <li>列表项</li>
        <li>列表项</li>
        <li>列表项</li>
        <li>列表项</li>
    </ul>

    <script>
        var oList = document.getElementById('list');
        var lis = oList.getElementsByTagName('li');

        // 书写循环语句,批量给元素添加监听
        for (var i = 0; i < lis.length; i++) {
            lis[i].onclick = function () {
                // 在这个函数中,this表示点击的这个元素
                this.style.color = 'red';
            };
        }
    </script>
</body>

</html>

使用for循环可以将每个li都添加按钮点击事件,但是每个li都是一个函数,函数本身是会占用内存的,于是接下来我们将介绍事件委托。

2.事件委托机制

  • 利用事件冒泡机制,将后代(比如li)元素事件委托给祖先(ul)元素。

  • 事件传播是:先从外到内捕获,然后从内到外冒泡。

  • 而事件监听有两种实现方式

  1. onxxx为DOM0级事件监听,只能监听冒泡阶段。即如果给元素设置相同的两个或多个同名事件,后面的会覆盖先写的。
    在这里插入图片描述
    在这里插入图片描述

  2. 另一种方式是addEventListener()方法,DOM2级事件监听,DOM.addEventListener('click',function(){},true);true表示监听捕获阶段,默认为false,监听冒牌阶段。
    在这里插入图片描述
    在这里插入图片描述

3.实现批量添加事件监听

实现点击每个li改变颜色

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <ul id="list">
        <li>列表项</li>
        <li>列表项</li>
        <li>列表项</li>
        <li>列表项</li>
        <li>列表项</li>
        <li>列表项</li>
        <li>列表项</li>
        <li>列表项</li>
        <li>列表项</li>
        <li>列表项</li>
        <li>列表项</li>
        <li>列表项</li>
        <li>列表项</li>
        <li>列表项</li>
        <li>列表项</li>
        <li>列表项</li>
        <li>列表项</li>
        <li>列表项</li>
        <li>列表项</li>
        <li>列表项</li>
    </ul>

    <script>
        var oList = document.getElementById('list');
        // var lis = oList.getElementsByTagName('li');

		oList.onclick = function(e){
			e.target.style.color = 'red';
		}
  
    </script>
</body>

</html>

注意:e.target属性触发此事件的最早元素,即用户真正点击的那个元素
e.currentTargent属性事件处理程序附加到的元素(跟this类似),表示祖先本身

4.事件委托的使用场景

  • 当有大量类似元素需要批量添加事件监听时,可以减少内存开销
  • 当有动态元素节点上树时,可以让新上树的元素具有事件监听。下面将有个小案例。

实现如下效果,动态添加li元素,然后点击每个li都触发删除事件。

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
    </style>
</head>

<body>
    <input type="text" class="textInput">
    <button id="btn">添加</button>
    <ul class="list">
        <li class="li">吃饭</li>
        <li class="li">睡觉</li>
        <li class="li">打豆豆</li>
    </ul>
    <script>
        // 获取元素
        var textInput = document.querySelector(".textInput")
        var btn = document.querySelector("#btn")
        var list = document.querySelector(".list")
        var li = document.querySelectorAll(".li")
        // 给按钮绑定点击事件
        btn.onclick = function () {
            var li = document.createElement("li");//创建li元素
            li.className = "li";
            li.innerHTML = textInput.value;
            list.appendChild(li);	//一定要将新增的li上树,不然点击事件对于新增的li无用,而且界面上也不会显示新增li
            textInput.value = "";
        }
        // 给li绑定点击事件
		//给祖先元素添加事件监听,利用冒泡机制,执行子元素。
            list.onclick = function (e) {
                list.removeChild(e.target);
            }
    </script>
</body>

</html>

5.注意事项

  • onmouseenter和onmouseover都表示“鼠标进入”
  1. onmouseenter不冒泡;相当于后代元素动作附加给了祖先元素,就是祖先元素做了动作。比如鼠标放一个li相当于整个ul都放了。无法给每个li单独添加事件效果
  2. onmouseover冒泡
  • 最内层元素(重复的元素比如li)不能再有额外的内层元素(比如span)了。因为当鼠标放在span上时,就会只有span项发生变化。在这里插入图片描述
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值