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>

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

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


<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .tbody-line:nth-child(2n) {
            background-color: skyblue;
        }
        
        td:hover{
          
            border: 10px solid #f00;
        }
    </style>
</head>

<body>
    <table border="1px sold #ccc" style="border-collapse:collapse;width:60%;margin:10px auto">
        <thead style="background-color: greenyellow">
            <tr>
                <td colspan="6" style="text-align: center;font-weight: bold;">课程表</td>
            </tr>
        </thead>
        <tbody>
            <tr class="tbody-line">
                <td>节数</td>
                <td>星期一</td>
                <td>星期二</td>
                <td>星期三</td>
                <td>星期四</td>
                <td>星期五</td>

            </tr>
            <tr class="tbody-line">
                <td>第一节</td>
                <td>课程1</td>
                <td>课程2</td>
                <td>课程3</td>
                <td>课程4</td>
                <td>课程5</td>

            </tr>
            <tr class="tbody-line">
                <td>第二节</td>
                <td>课程1</td>
                <td>课程2</td>
                <td>课程3</td>
                <td>课程4</td>
                <td>课程5</td>

            </tr>
            <tr class="tbody-line">
                <td>第三节</td>
                <td>课程1</td>
                <td>课程2</td>
                <td>课程3</td>
                <td>课程4</td>
                <td>课程5</td>

            </tr>
            <tr class="tbody-line">
                <td>第四节</td>
                <td>课程1</td>
                <td>课程2</td>
                <td>课程3</td>
                <td>课程4</td>
                <td>课程5</td>

            </tr>
        </tbody>
    </table>
</body>

</html>