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

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

问题回顾

当我们想给一个列表中的每个列表项添加相同的事件时,我相信最先想到的方法一定是事件委托,通过将事件监听器设置在其父节点上,利用事件冒泡的原理实现想要的操作,这样只进行了一次的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方法选择出我们所要的列表项节点。

相关文章
|
6月前
|
小程序
小程序中点击子元素事件而不触发父元素的点击事件
小程序中点击子元素事件而不触发父元素的点击事件
104 0
|
8月前
|
JavaScript
jq样式、元素操作,效果,筛选方法与转换,事件对象
jq样式、元素操作,效果,筛选方法与转换,事件对象
|
4月前
|
JavaScript
JS事件,你真的懂吗(捕获,冒泡)?
JS事件,你真的懂吗(捕获,冒泡)?
31 0
|
8月前
mouseover、mouseout和mouseenter、mouseleave之间的区别(配对使用)
mouseover、mouseout和mouseenter、mouseleave之间的区别(配对使用)
|
9月前
|
JavaScript
请解释什么是事件代理
请解释什么是事件代理
uiu
|
JavaScript 调度
【Svelte】-(5)DOM事件 / 事件修饰符 / 组件事件 / 事件转发 (组件之间的事件沟通)
【Svelte】-(5)DOM事件 / 事件修饰符 / 组件事件 / 事件转发 (组件之间的事件沟通)
uiu
151 0
【Svelte】-(5)DOM事件 / 事件修饰符 / 组件事件 / 事件转发 (组件之间的事件沟通)
|
JavaScript 前端开发
史上最详细的DOM事件之拖动事件
史上最详细的DOM事件之拖动事件 上篇博客讲了DOM的剪贴板事件,这篇博客我们来讲一讲DOM的拖动(DragEvent)事件。 HTMl代码: &lt;img src=&quot;../../CSS/0421/car.jpg&quot; draggable=&quot;false&quot;&gt; 1 JS代码: var oImg=document.getElementsByTagName(&quot;img&quot;)[0]; // DragEvent 拖动事件 // ondrag 该事件在元素正在拖动时触发 oImg.ondrag=function(ev){ console
|
JavaScript
13、JS事件(事件绑定、事件流、阻止事件冒泡、取消元素默认行为)
13、JS事件(事件绑定、事件流、阻止事件冒泡、取消元素默认行为)
89 0
|
Web App开发 前端开发 iOS开发
使用 tabindex 配合 focus-within 巧妙实现父选择器
使用 tabindex 配合 focus-within 巧妙实现父选择器
125 0
使用 tabindex 配合 focus-within 巧妙实现父选择器
这种方式写冒泡,更简单
接上一篇,来自我的好朋友,EvilSay 投稿的文章。以下是原文: