Allen's blog Allen's blog
首页
面经
算法 (opens new window)
分类

Allen

前端CV工程师
首页
面经
算法 (opens new window)
分类
  • Javascript

  • TypeScript

  • CSS

  • Vue

  • React

  • 框架和构建工具

  • 工具库

  • 常见业务场景

    • 事件委托
      • 事件委托的优点
      • 遇到的问题
      • 方案
    • 滚动条闪动解决方案
    • 列表拖拽排序
    • linear-gradient背景渐变色
    • 表格组件数据加载,排序等
    • 时间业务
    • 滚动加载
    • 文件下载
  • Bug

  • 项目实战

  • 前端
  • 常见业务场景
Allen
2023-03-27
目录

事件委托

# 事件委托的优点

  • 将事件绑定到目标元素的父级或者更上一级,不需要给所有的元素都绑定事件,减少内存占用空间,提升性能。
  • 动态新增的元素无需重新绑定事件

# 遇到的问题

网络上很多讲解事件委托的例子都是举的:

<ul id="myLink">
  <li id="1">aaa</li>
  <li id="2">bbb</li>
  <li id="3">ccc</li>
</ul>
1
2
3
4
5

这样的例子复杂度不够,不太能覆盖到实际场景,往往实际中,v-for 循环出一个个 item,而 item 内部有很多个元素,或者 item 内元素还存在嵌套关系,当发生点击事件时,捕捉到的 event.target 不一定是我们需要执行操作的目标元素。举个例子:

<ul id="myLink">
    <li id="1">
        <a>
            <img src="xxx" />
            <span>查看大图</span>
            <span>评论</span>
        </a>
    </li>
    <li id="2">
        <a>
            <img src="yyy" />
            <span>查看大图</span>
            <span>评论</span>
        </a>
    </li>
    <li id="3">
        <a>
            <img src="zzz" />
            <span>查看大图</span>
            <span>评论</span>
        </a>
    </li>
</ul>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

我们将事件委托到外层元素ul上,得到event.target,“查看大图”和“评论”的事件回调不相同,而event.target捕获的可能是 a 标签,可能是 img 标签,可能是 span 标签,那么我们如何判断点击的元素是否是目标元素呢?

# 方案

可以给目标元素上添加一个标识,如果event.target上有这个标识,则得到目标元素,触发相应回调,否则就往父级元素上寻找是否有目标标识,直到event.target === event.currentTarget停止查找。

这个唯一标识可以是类名,可以是自定义属性。

我遇到一个场景,在点击非热点区域要调用一个接口,这个接口需要这个列表项的 id,我是直接定义了一个自定义属性,值为 id,当事件捕捉到的元素上有这个自定义属性时,就读取 id,发送请求。

<ul @click="handleClick">
    <li v-for="(item,index) in dataList" :key=item.id id="item.id">
        <a>
            <img :src="item.img" />
            <span :data-image-view="item.id">查看大图</span>
            <span data-comment>评论</span>
        </a>
    </li>
</ul>
1
2
3
4
5
6
7
8
9
const handleClick = (e) => {
    let element = e.target
    while (!element.dataset.imageView) {
        // 如果当前节点没有目标属性,则向父级寻找
        element = element.parentNode
        if (element === e.currentTarget) {
            // 找到最外层了,直接退出
            return
        }
    }
    // 找到目标元素了,获取值,然后调接口
    jumpToDetail(element.dataset.imageView)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
上次更新: 2023/12/16, 09:22:46
fundlint代码规范工具开发
滚动条闪动解决方案

← fundlint代码规范工具开发 滚动条闪动解决方案→

最近更新
01
rollup使用配置文件rollup.config.ts打包
12-08
02
package.json导出类型
12-08
03
关键问题方案
11-17
更多文章>
Theme by Vdoing | Copyright © 2023-2023 Allen | Github
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式