跳至主要內容

元素外部点击事件

wzCoding大约 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'),
)