事件委托

100 阅读2分钟

样式代码

 <style>
    ul {
        width: 500px;
        background-color: pink;
    }

    li {
        width: 200px;
        background-color: green;
        margin-top: 5px;
    }
</style>

body代码

    <ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
    <li>5</li>
    <li>6</li>
    <li>7</li>
    <li>8</li>
    <li>9</li>
    <li>10</li>
</ul>

事件委托

就是要把我自己做的事, 委托给别人, 帮我完成

因为我们的冒泡机制, 点击子元素的时候, 也会同步触发父元素的相同事件

所以我们可以把子元素的事件委托给父元素来做

点击子元素的时候, 不管子元素有没有点击事件, 只要父元素有点击事件, 那么就可以触发父元素的点击事件

    var oUl = document.querySelector('ul')
    oUl.onclick = function () {
        console.log('我是 UL 的点击事件, 我被触发了')
    }

target

这个属性是事件对象里的属性, 表示你点击的目标

这个 target 兼容性有问题, 在 IE 浏览器内 需要使用 srcElement 语法: e.srcElement (了解即可)

    var oUl = document.querySelector('ul')
    oUl.onclick = function (e) {
        if (e.target.nodeName === 'LI') {
            console.log('我是 li 标签, 我被点击了~~~')
        }
    }

事件委托的优点

页面上本身没有 li, 通过 代码添加了一些 li

这些 li 是没有点击事件的, 每次动态的添加 li, 还需要从新给 li 绑定一次点击事件

这时候使用事件委托就比较合适

因为: 新加进来的 li 也是 ul 的子元素, 点击的时候也可以触发 ul 的点击事件

扩展案例

需求: 给 Ul 内部的 所有 li 添加一个 点击事件, 但是不能使用事件委托

样式代码

   <style>
    ul {
        width: 500px;
        background-color: pink;
    }

    li {
        width: 200px;
        background-color: green;
        margin-top: 5px;
    }
</style>

body代码

 <ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
</ul>
0. 获取元素
    var lis = [...document.querySelectorAll('li')]
    var oUl = document.querySelector('ul')
1. 遍历数组, 给目前结构内所有的 li 添加一个点击事件
       lis.forEach(function (item) {
            item.onclick = function () {
                console.log('我点击了 li')
        }
    })
1.1 利用事件委托解决
    oUl.onclick = function (e) {
        if (e.target.nodeName === 'LI') {
            console.log('我点击了 li')
        }
    }
2. 创建一个 li 节点并添加到 ul 内
    var newLi = document.createElement('li')
    newLi.innerText = '我是通过 JS 创建的 li 节点'
    oUl.appendChild(newLi)