元素外部点击事件
大约 2 分钟
元素外部点击事件
点击事件通常都是由绑定了点击事件的元素触发的,但是在某些情况下,我们也会有监听是否在目标元素的外部区域触发了点击事件的需求。
监听外部点击事件
//一个简单的监听是否在目标元素之外触发了点击事件的函数
//接收 3 个参数:
//1. 目标元素
//2. 在目标元素外部触发点击事件后执行的回调函数
//3. 需要排除的元素(即使在目标元素之外触发了点击事件,这部分元素也不会触发回调执行)
function clickOutSide(target, callback, exclude) {
if (!target) return
//将需要排除的元素参数归一化处理
if (!Array.isArray(exclude)) {
exclude = [exclude]
}
const excludeElements = exclude.filter(Boolean)
//点击事件的处理函数
const handleClick = (event) => {
//获取目标元素的尺寸与位置信息
const { x, y, width, height } = target.getBoundingClientRect()
//计算目标元素的结束位置
const endX = x + width
const endY = y + height
//排除 exclude 参数中的元素
if (excludeElements.length && excludeElements.some(item => item.contains(event.target))) return
// 判断触发点击事件的元素的坐标位置是否与目标元素有重叠
else if ((event.clientX > endX || event.clientX < x || event.clientY > endY || event.clientY < y)) {
//执行回调
callback && callback()
}
}
//给页面绑定点击事件
document.addEventListener('click', handleClick)
//返回一个清除监听点击事件的函数,以便在合适的时候移除对整个页面点击事件的监听
return () => {
document.removeEventListener('click', handleClick)
}
}
//使用
<div class="inner"> inner </div>
<div class="exclude"> exclude </div>
const clean = clickOutSide(
//目标元素
document.querySelector('.inner'),
//回调函数
()=>{
console.log('点击了外部')
//在这里清除点击事件
clean()
},
//这里的元素不会触发回调函数的执行
document.querySelector('.exclude'),
)