准确获取事件源的任意父级元素(事件委托)

简介: 事件委托的特殊用法

问题回顾

当我们想给一个列表中的每个列表项添加相同的事件时,我相信最先想到的方法一定是事件委托,通过将事件监听器设置在其父节点上,利用事件冒泡的原理实现想要的操作,这样只进行了一次的dom操作,提高了程序的性能。通常我们都会使用事件源e.target来获取点击的元素,从而可以知道我们点击的是谁。


当我们处理的结构是像这样简单的ul > li时,这种方法就非常好用,e.target获取到的事件源就是li

<ul>
       <li>1</li>
       <li>2</li>
       <li>3</li>
       <li>4</li>
       <li>5</li>
</ul>

但是当我们遇到的情况是这样的呢  

image.png

需要实现的功能是,点击这个盒子区域,输出对应的li对应的id,下面是这个li对应的代码片段,很显然在li内部存在着大量的子元素,我们需要通过给li的父元素ul绑定事件,从而实现事件委托,那么我们该如何确定我们点击的元素属于哪一个li呢?下面开始正文!

<li id="mainArticleId24">
    <div class="contentBox">
        <div class="newsBox">
            <div class="newsTime">
                <ul>
                    <li class="authorName colorBlue">ljc</li>
                </ul>
            </div>
            <div class="newsTitle">
                <span>content</span>
            </div>
            <div class="newsBtn">
                <ul class="newsUl">
                    <li class="false">
                        <i class="good">1</i>
                        <span class="clickNum">2</span>
                    </li>
                    <li class="false">
                        <i class="worse">1</i>
                        <span class="clickNum">2</span>
                    </li>
                    <li class="shareIcon">
                        <i class="share">3</i>
                    </li>
                </ul>
            </div>
        </div>
    </div>
</li>

抛出问题

在上面的代码中我们发现,我们通过事件源e.target不能直接的获取到我们想要的li了,从而导致我们获取不到id无从下手


解决方法

下面我通过另一种方法很好的解决了这个问题


在我们的事件对象event中,存在着一个方法path,这个方法可以返回事件触发的所有父元素,我们可以使用这个方法,完美的解决我们现在存在的问题!


我们先通过e.path获取到事件触发对象的所有的所有元素,这个方法的返回值是一个数组,我们可以通过数组中的find方法按照我们的需求选择我们想要的元素,在下面的代码中,我们先给每一个li添加一个特有的标志属性sign,通过判断e.path返回的数组中是否含有这个属性,从而来确定事件触发元素的li,进而解决了我们的问题

注意:localName属性是确定元素的标签,像div li这些就属于localName,整个方法的核心就是通过获取到触发事件元素的所有父元素集合,再通过筛选从而获得元素!


注意:每个li是位于同级的是兄弟关系,所以返回的数组中只会存在一个这样的li

let temp = e.path.find(num => {
    if (num.localName == 'li' && num.className == 'sign') {
           return num
    }
})

总结 当我们利用事件委托给列表中的所有列表项添加事件时,在实际开发中列表项中往往会有大量的子元素,因此我们可以通过事件对象下的path方法以及数组中的find方法选择出我们所要的列表项节点。

相关文章
|
存储 前端开发 JavaScript
React中如何动态添加和删除元素
React中如何动态添加和删除元素
482 0
|
监控 开发者 Python
Python 默认 `logging` 打印级别详解
本文详细介绍了 Python `logging` 模块的默认打印级别及其配置方法。`logging` 模块支持 `DEBUG`、`INFO`、`WARNING`、`ERROR` 和 `CRITICAL` 五个日志级别,默认级别为 `WARNING`。文章通过示例代码展示了如何设置和使用不同日志级别,并介绍了进一步的配置选项,如日志格式和文件输出。
547 8
|
存储
在使用 realloc 函数时,如何避免数据丢失?
在使用 realloc 函数动态调整内存大小时,为避免数据丢失,应先将原指针保存到临时变量中,调用 realloc 后检查返回值是否为 NULL,若为 NULL 则保留原指针,否则更新指针并释放临时变量。
|
算法
数据结构之文件系统模拟(树数据结构)
本文介绍了文件系统模拟及其核心概念,包括树状数据结构、节点结构、文件系统类和相关操作。通过构建虚拟环境,模拟文件的创建、删除、移动、搜索等操作,展示了文件系统的基本功能和性能。代码示例演示了这些操作的具体实现,包括文件和目录的创建、移动和删除。文章还讨论了该算法的优势和局限性,如灵活性高但节点移除效率低等问题。
272 0
|
XML 前端开发 JavaScript
[selenium]元素定位
[selenium]元素定位
205 1
|
消息中间件 微服务
RabbitMQ入门指南(十):延迟消息-死信交换机
RabbitMQ是一个高效、可靠的开源消息队列系统,广泛用于软件开发、数据传输、微服务等领域。本文主要介绍了死信交换机、死信交换机实现延迟消息等内容。
512 0
|
缓存 监控 前端开发
React 代码优化方案
【8月更文挑战第19天】React 代码优化方案
271 0
|
NoSQL 关系型数据库 MySQL
30K成功入职京东:拿到京东offer经验分享「面试经历+面试真题」
前言 ​目前很多大型互联网公司都采用线上面试的方法来挑选人才,也有很多幸运的小伙伴也是拿到大厂的offer,今天给大家分享的是我一位幸运拿到京东offer的朋友的面试经历,上周末,我也闲来无事,问到了我朋友京东面试的一些真题,以及我整理的一些真题分享给大家。
814 0
|
机器学习/深度学习 人工智能 并行计算
声音好听,颜值能打,基于PaddleGAN给人工智能AI语音模型配上动态画面(Python3.10)
PaddlePaddle是百度开源的深度学习框架,其功能包罗万象,总计覆盖文本、图像、视频三大领域40个模型,可谓是在深度学习领域无所不窥。 PaddleGAN视觉效果模型中一个子模块Wav2lip是对开源库Wav2lip的二次封装和优化,它实现了人物口型与输入的歌词语音同步,说白了就是能让静态图的唇部动起来,让人物看起来仿佛正在唱歌。 除此以外,Wav2lip还可以直接将动态的视频,进行唇形替换,输出与目标语音相匹配的视频,如此一来,我们就可以通过AI直接定制属于自己的口播形象了。
声音好听,颜值能打,基于PaddleGAN给人工智能AI语音模型配上动态画面(Python3.10)
|
大数据 网络安全
zookeeper集群搭建超详细教程
分享一下zookeeper集群搭建的详细过程
831 1