当我们给父元素利用委托来给子元素添加监听事件时,会遇到这样一种情况,就是子元素里面也嵌套了很多子元素当我们点击时返回不是我们想要的二级子元素,而是子元素里面嵌套的子元素。
解决方法
方法一、
给每一个子元素添加css: pointer-events : none (当设置为none时,元素则不接收hover、click事件,由他的父元素进行接收)
span {
pointer-events: none;
}
p {
pointer-events: none;
}
<ul>
<li>
<span>你好</span>
<p>你在说什么</p>
</li>
<li>
<span>你好</span>
<p>你在说什么</p>
</li>
</ul>
-----------------------------------
如果这种结构 直接给div加就可以
div {
pointer-events: none;
}
<li>
<div>
<span>你好</span>
<p>你在说什么</p>
</div>
</li>
方法二、
给点击元素的子元素都添加一个自定义属性,确保点击每个子元素都能返回相同的值
局限性:
当你只是需要给该元素添加类或者改变样式时就会很麻烦
<ul>
<li data-id = '1'>
<span data-id = '1'>你好</span>
<p data-id = '1'>你在说什么</p>
</li>
<li data-id = '2'>
<span data-id = '2'>你好</span>
<p data-id = '2'>你在说什么</p>
</li>
</ul>
方法三、
利用==event.composedPath()==获取当前冒泡事件经过的所有元素并返回为一个数组。
冒泡事件是当前元素往上层父元素进行冒泡,所以第0个就是当前点击的元素,如果为事件捕获则相反。
利用当前点击元素的标签名或者类名和ID名进行判断查找就能找到我们想要的元素。
js代码
const ul = document.querySelector('ul')
ul.addEventListener('click', (event) => {
// 去除父盒子 判断
第0个就是当前点击的元素
if (event.composedPath()[0] == 'UL') {
return
}
// find()方法用于查找数组中符合条件的第一个元素,如果没有符合条件的元素,则返回undefined
let b = event.composedPath().find(element => {
if (element.tagName == 'LI') {
return element
}
})
console.log(b); // 获取的当前元素
})
方法四、排除法(算是最简单的方法)
<ul>
<li>
<span>你好</span>
<p>你在说什么</p>
<div></div>
</li>
</ul>
const ul = document.querySelector('ul')
ul.addEventListener('click', (event) => {
// 排除法 不是LI的全部return
if (event.target.tagName !== 'LI') return
}