Vue 3中如何点击同一位置的两个或多个元素?
Vue3 处理重叠元素点击的简便方法
下面几种方案可以解决同一位置多个元素的点击问题:
方案1:通过切换pointer-events控制可点击状态
默认只让最上层元素响应点击,点击后切换下层元素的可点击状态,实现依次触发不同元素的点击事件。
<template> <div class="point-container"> <div v-for="(point, index) in points" :key="index" class="point" :style="{ top: `${point.y}px`, left: `${point.x}px`, pointerEvents: point.isClickable ? 'auto' : 'none' }" @click="handlePointClick(index)" ></div> </div> </template> <script setup> import { ref } from 'vue' const points = ref([ { x: 100, y: 100, isClickable: false }, { x: 100, y: 100, isClickable: true } // 初始仅最上层可点击 ]) const handlePointClick = (index) => { // 处理当前点击元素的业务逻辑 console.log('点击了第', index + 1, '个点') // 切换下一个可点击元素 points.value[index].isClickable = false const nextIndex = (index + 1) % points.value.length points.value[nextIndex].isClickable = true } </script> <style scoped> .point-container { position: relative; width: 100%; height: 400px; } .point { position: absolute; width: 20px; height: 20px; border-radius: 50%; background: rgba(255, 0, 0, 0.5); } </style>
方案2:通过点击坐标检测所有重叠元素
监听容器的点击事件,通过元素的位置判断点击坐标是否命中元素,一次性获取所有重叠的点击目标,再按需处理。
<template> <div class="point-container" @click="handleContainerClick"> <div v-for="(point, index) in points" :key="index" class="point" :style="{ top: `${point.y}px`, left: `${point.x}px` }" ref="pointRefs" ></div> </div> </template> <script setup> import { ref } from 'vue' const points = ref([ { x: 100, y: 100, id: 'point-1' }, { x: 100, y: 100, id: 'point-2' } ]) const pointRefs = ref([]) const handleContainerClick = (e) => { const { clientX, clientY } = e const hitPoints = [] pointRefs.value.forEach((el, idx) => { const rect = el.getBoundingClientRect() // 判断点击坐标是否在元素范围内 const isHit = clientX >= rect.left && clientX <= rect.right && clientY >= rect.top && clientY <= rect.bottom if (isHit) hitPoints.push(points.value[idx]) }) if (hitPoints.length) { // 这里可以根据需求处理所有命中的元素,比如弹出选择面板或依次触发逻辑 console.log('命中的元素:', hitPoints) hitPoints.forEach(point => { console.log('处理元素:', point.id) }) } } </script> <style scoped> .point-container { position: relative; width: 100%; height: 400px; } .point { position: absolute; width: 20px; height: 20px; border-radius: 50%; background: rgba(0, 0, 255, 0.5); } </style>
方案3:切换元素z-index层级
点击后将当前元素的层级设为最低,让下层元素上浮,下次点击即可触发下层元素的事件。
<template> <div class="point-container"> <div v-for="(point, index) in points" :key="index" class="point" :style="{ top: `${point.y}px`, left: `${point.x}px`, zIndex: point.zIndex }" @click="handlePointClick(index)" ></div> </div> </template> <script setup> import { ref } from 'vue' const points = ref([ { x: 100, y: 100, zIndex: 1 }, { x: 100, y: 100, zIndex: 2 } // 初始最上层 ]) const handlePointClick = (index) => { console.log('点击了第', index + 1, '个点') // 将当前元素层级设为最低,其他元素层级递增 const minZ = Math.min(...points.value.map(p => p.zIndex)) - 1 points.value[index].zIndex = minZ points.value.forEach((p, idx) => { if (idx !== index) p.zIndex += 1 }) } </script> <style scoped> .point-container { position: relative; width: 100%; height: 400px; } .point { position: absolute; width: 20px; height: 20px; border-radius: 50%; background: rgba(0, 255, 0, 0.5); } </style>
内容的提问来源于stack exchange,提问作者Trottenheimer
相关产品推荐
相关产品推荐

