uni-app中如何用好css pointer-events属性实现当前元素不可被点击,穿透点击到层级低的视图

发布于 1周前 作者 sinazl 来自 uni-app

uni-app中如何用好css pointer-events属性实现当前元素不可被点击,穿透点击到层级低的视图

官方文档

https://developer.mozilla.org/zh-CN/docs/Web/CSS/pointer-events

pointer-events: auto; 与 pointer-events 属性未指定时的表现效果相同,对于 SVG 内容,该值与 visiblePainted 效果相同
pointer-events: none; 元素永远不会成为鼠标事件的 target。但是,当其后代元素的 pointer-events 属性指定其他值时,鼠标事件可以指向后代元素,在这种情况下,鼠标事件将在捕获或冒泡阶段触发父元素的事件侦听器。

下面这个例子是不会触发 onTap 事件的

<template>  
    <view>  
        <view class="a"></view>  
        <view class="b" @tap="onTap"></view>  
    </view>  
</template>  

<script>  
export default {  
    methods: {  
        onTap() {  
            console.log("点击了 b");  
        }  
    }  
}  
</script>  

<style lang="scss" scoped>  
    .a {  
        position: fixed;  
        top: 0;  
        left: 0;  
        right: 0;  
        height: 100vh;  
        z-index: 10;  
    }  
    .b {  
        width: 100px;  
        height: 100px;  
        background-color: aqua;  
    }  
</style>

下面这个例子会触发 onTap 事件的,在 a 的样式加上 pointer-events: none;,b 的样式加上 pointer-events: auto; 其他不变

<template>  
    <view>  
        <view class="a"></view>  
        <view class="b" @tap="onTap"></view>  
    </view>  
</template>  

<script>  
export default {  
    methods: {  
        onTap() {  
            console.log("点击了 b");  
        }  
    }  
}  
</script>  

<style lang="scss" scoped>  
    .a {  
        position: fixed;  
        top: 0;  
        left: 0;  
        right: 0;  
        height: 100vh;  
        z-index: 10;  
        pointer-events: none;  
    }  
    .b {  
        width: 100px;  
        height: 100px;  
        background-color: aqua;  
        pointer-events: auto;  
    }  
</style>

↓↓↓ 各位大佬点点赞


1 回复

在uni-app中,pointer-events 属性是一个非常有用的CSS属性,它决定了元素是否成为鼠标事件的目标。通过设置 pointer-events 属性,你可以控制一个元素是否响应点击、触摸等事件,甚至可以让这些事件穿透当前元素,作用到其下方的元素上。

要实现当前元素不可被点击,同时让点击事件穿透到层级低的视图,你可以将 pointer-events 属性设置为 none。下面是一个简单的代码示例,展示了如何在uni-app中使用这一属性。

示例代码

1. 在页面的 .vue 文件中添加结构

<template>
  <view class="container">
    <view class="overlay" @click="handleOverlayClick">Overlay (不可点击)</view>
    <view class="content">Content (可点击)</view>
  </view>
</template>

<script>
export default {
  methods: {
    handleOverlayClick() {
      console.log('Overlay clicked, but this should not happen');
    }
  }
}
</script>

<style scoped>
.container {
  position: relative;
  width: 100%;
  height: 100vh;
}

.overlay {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.5); /* 半透明遮罩 */
  pointer-events: none; /* 使overlay不可点击,点击穿透 */
}

.content {
  position: relative; /* 确保content在overlay上方显示(虽然pointer-events已使overlay无效) */
  z-index: 1; /* 可选,确保content在视觉上位于overlay之上 */
  width: 80%;
  height: 80%;
  background-color: white;
  margin: 10% auto;
  text-align: center;
  line-height: 80vh;
}
</style>

2. 解释

  • .overlay 类应用了 pointer-events: none;,这意味着虽然 .overlay 覆盖了整个屏幕,但它不会响应任何点击事件。
  • 点击 .overlay 时,事件会穿透到其下方的 .content 元素上(如果 .content 在视觉上是位于 .overlay 之上的,这通常是通过 z-index 和 position 属性来控制的)。
  • 在这个例子中,.content 元素是可点击的,即使它被 .overlay 覆盖。

通过这种方式,你可以在uni-app中有效地利用 pointer-events 属性来实现元素的点击穿透效果,这对于创建模态窗口、加载遮罩等场景非常有用。

回到顶部