vue3 自制抽屉 Dom元素时一些疑问

目的,做 一个 点击弹出的 抽屉 dom, 点击dom外面,该dom隐藏

下 面  代码错在哪?  


  const drawerVisible = ref<boolean>(false)  //    控制抽屉 div 的显示
  const refDrawer = ref<any>() //  ref绑定了抽屉 div dom元素


// 点击显示 drawer,  注意:鼠标点击位置在 drawer元素外面, drawer点击前没有显示
  function drawerPosition(){  
    if(!drawerVisible.value){
      drawerVisible.value = true  // 显示 drawer
      document.addEventListener('click',eventInfo)  // 开始监听鼠标点击位置,
    }
  }
  function eventInfo(e:any){  // click 监听的回调
    if(e.clientX < refDrawer.value.offsetLeft  // 当鼠标点击在 drawer 元素外面时关闭 drawer
      || e.clientY < refDrawer.value.offsetTop
      ){
      drawerVisible.value = false
    }
  }
  // 关闭监听事件. 
  watch(()=> drawerVisible.value,(newValue)=>{ // 当 drawerVisible.value等于false时关闭监听
     // 问题在这,发现每次点击,  drawerVisible.value 变成 true 又马上变成 false
    console.log('发生了变化',newValue)  // 
    if(!newValue){
      document.removeEventListener('click',eventInfo) // 关闭监听事件
    } 
  })


请教有没有更简便的方法. 达到点击 元素外面 ,隐藏元素自身的方法?

用事件对象的stopPropagation阻止冒泡执行document.onclick事件+dom元素contains判断下是否点击到弹出元素,示例代码如下

<div onclick='drawerPosition(event)'>Show</div>
<div id="pop" style="display:none;width:100px;height:100px;background:#ccc;display:none">
    <div>Sub div1</div>
    <div>Sub div2</div>
    <div>Sub div3</div>
</div>
<script>
    function drawerPosition(e) {
        pop.style.display = pop.style.display == 'block' ? 'none' : 'block';//切换
        e.stopPropagation();//阻止冒泡执行document.onclick事件
    }
    document.onclick = function (e) {
        var t = e.target;//获取点击的元素
        if (t == pop || pop.contains(t)) return;//点击的元素是弹出层或者弹出层子元素,退出
        pop.style.display = 'none';
    }
</script>


img

domElement.contains方法了解一下

在点击显示 drawer的事件, 和drawer元素的点击事件中加e.stopPropagation()停止事件向上冒泡即可

通过z-index将元素设置在最顶层,元素的下面一层为一个全屏的透明的div,div设置点击事件,点击是隐藏元素

您好,我是有问必答小助手,您的问题已经有小伙伴帮您解答,感谢您对有问必答的支持与关注!
PS:问答VIP年卡 【限时加赠:IT技术图书免费领】,了解详情>>> https://vip.csdn.net/askvip?utm_source=1146287632