满口金牙 2022-06-12 18:21 采纳率: 91.1%
浏览 176
已结题

Vue Position 的元素 挡住下面的元素,无法监听到 鼠标移动,请教

目的:框选 表格中单元格 ,外面出现一个绿色的边框。
思路: 把选取的单元格 外套上一个 绿色边框的 div
问题描述:当框选 大了时, 无法通过移动鼠标缩小,这时,鼠标要移入 绿色div内 ,
但 绿色边框的 div挡住了下面的td元素 ,无法监听到鼠标移动至的目标,
所以也改不了 绿色边框的 div 的位置 和 大小

img

<table id='form_table' ref='ref_table' class="form-table" @mousedown = "handleMouseDown" >
  <tr>
    <td id="1-1">1-1</td>
    <td id="1-2">1-2</td>
    <td id="1-3" rowspan="2">1-3</td>
    <td id="1-4">1-4</td>
    <td id="1-5">1-5</td>
  </tr>
..略
  <div id="select_range" :class="rangeBoxStyle">
</div>
</table>

<script setup lang="ts">
import { ref, reactive, onMounted} from 'vue'
const ref_table = ref<string>()
const rangeBoxStyle = ref<string>('range-box-none')
const rangeBoxPosition = reactive({
  left:'',top:'',width:'',height:'',
})
const cellRange = reactive({
    start:{ // 4个角的座标
      a:{x:1,y:2},
      b:{x:1,y:2},
      c:{x:1,y:2},
      d:{x:1,y:2},
    },
    end:{
      a:{x:1,y:2},
      b:{x:1,y:2},
      c:{x:1,y:2},
      d:{x:1,y:2},
    }
})

//鼠标按下事件
const handleMouseDown = (event:any)=> {
  // 记录第一个点击目标 4个角的座标 x,y 由于框选的方向不一样,所以要记录4个角的座标 x,y
  cellRange.start = {
    a: { x:event.target.offsetLeft, y:event.target.offsetTop },
    b: { x:event.target.offsetLeft + event.target.offsetWidth, y:event.target.offsetTop},
    c: { x:event.target.offsetLeft + event.target.offsetWidth, y:event.target.offsetTop + event.target.offsetHeight},
    d: { x:event.target.offsetLeft, y:event.target.offsetTop + event.target.offsetHeight}
  } 
  // 给当前元素套一层,  绿色边框的div, 并显示出来
  rangeBoxPosition.left = cellRange.start.a.x + 'px' // 绿色边框的div  position 定位的 left, 值绑定在 style 类属性中
  rangeBoxPosition.top = cellRange.start.a.y + 'px'  // 绿色边框的div  position 定位的 top, 值绑定在 style 类属性中
  rangeBoxPosition.width = event.target.offsetWidth + 'px' // 绿色边框的div 宽度
  rangeBoxPosition.height = event.target.offsetHeight + 'px' // 绿色边框的div 高度
  rangeBoxStyle.value = 'range-box-show' // 显示出来 (更改类名来显示)

  const form_table = document.getElementById('form_table') as HTMLTableElement
  form_table.addEventListener("mousemove", handleMouseMove) //监听鼠标移动事件
  form_table.addEventListener("mouseup", handleMouseUp) //监听鼠标抬起事件
}
// 问题在这里!!,当框选, 框选大了时, 无法移动鼠标来缩小,   绿色边框的div 挡着了下面的元素,无法再监听到鼠标的移动
function  handleMouseMove(event:any) {
  // 根据鼠标移动的位置来调整,绿色边框的div的大小和位置:
  if(event.target.id == 'select_range' || event.target.id =='form_table') return
  cellRange.end = { // 当前鼠标移动到的目标位置
    a: { x:event.target.offsetLeft, y:event.target.offsetTop },
    b: { x:event.target.offsetLeft + event.target.offsetWidth, y:event.target.offsetTop},
    c: { x:event.target.offsetLeft + event.target.offsetWidth, y:event.target.offsetTop + event.target.offsetHeight},
    d: { x:event.target.offsetLeft, y:event.target.offsetTop + event.target.offsetHeight}
  } 
  // 如果相对第一个点击元素: 水平方向和右方向移动鼠标 ,计算出 绿色边框的div 位置 和 宽高
  if(cellRange.end.a.x >= cellRange.start.a.x && cellRange.end.a.y >= cellRange.start.a.y){
    rangeBoxPosition.left = cellRange.start.a.x + 'px' // 绿色边框的div  position 定位的 left
    rangeBoxPosition.top = cellRange.start.a.y + 'px'  // 绿色边框的div  position 定位的 top
    rangeBoxPosition.width = (cellRange.end.c.x - cellRange.start.a.x) + 'px' // 绿色边框的div 宽度
    rangeBoxPosition.height = (cellRange.end.c.y - cellRange.start.a.y) + 'px' // 绿色边框的div 高度
  }
 
  console.dir(`鼠标在移动的元素${event.target.id}:`)
  // event.stopPropagation()
}

function handleMouseUp() {
  // rangeBoxStyle.value = 'range-box-none'
  const form_table = document.getElementById('form_table') as HTMLTableElement

  form_table.removeEventListener("mousemove", handleMouseMove);
  form_table.removeEventListener("mouseup", handleMouseUp);
  // cellRange.is_show_mask = false;
}

onMounted(() => {
  // console.dir('ref-table',ref_table)
})


</script>
<style lang="scss">
@import '../../assets/css/handle';

.range-box-none{
  display: none;
  position: absolute;
}
.range-box-show{
  border:2px solid greenyellow;
  display: block;
  position: absolute;
  left: v-bind('rangeBoxPosition.left');
  top: v-bind('rangeBoxPosition.top'); // offsetTop
  width:v-bind('rangeBoxPosition.width'); // offsetLeft
  height: v-bind('rangeBoxPosition.height'); // offsetLeft
}

.form-table{
  margin:auto;
  margin-top: 100px;
  font-size: 12px;
  position: relative;
  // 让文字不可选
  user-select: none;
  -webkit-user-seletct: none;
  -moz-user-seletct: none;
  @include font_color('font_color2');
  tr,td{
    border: 1px solid rgb(188, 188, 188);
  }
  td{
    width: 100px;
  }
}
</style>

  • 写回答

3条回答 默认 最新

  • 关注

    绿色的边框div设置 style="pointer-events: none;"
    让鼠标事件穿透绿色的边框, 就可以让div挡住的td元素监听到鼠标移动事件了

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 6月20日
  • 已采纳回答 6月12日
  • 创建了问题 6月12日

悬赏问题

  • ¥15 FileNotFoundError 解决方案
  • ¥15 uniapp实现如下图的图表功能
  • ¥15 u-subsection如何修改相邻两个节点样式
  • ¥30 vs2010开发 WFP(windows filtering platform)
  • ¥15 服务端控制goose报文控制块的发布问题
  • ¥15 学习指导与未来导向啊
  • ¥15 求多普勒频移瞬时表达式
  • ¥15 如果要做一个老年人平板有哪些需求
  • ¥15 k8s生产配置推荐配置及部署方案
  • ¥15 matlab提取运动物体的坐标