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

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条回答

      报告相同问题?

      相关推荐 更多相似问题

      问题事件

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

      悬赏问题

      • ¥20 snmpv3相关提问
      • ¥20 boost电路升压频率和占空比选择
      • ¥15 找个人工智能的大佬咨询一些毕设问题
      • ¥15 需要教程:GD32F450I移植无系统lwip
      • ¥15 中文语料库检索构式 求助
      • ¥15 关于naver点击量信息
      • ¥15 Linux gcc升级问题
      • ¥100 如何封禁域名,让app打不开呢?
      • ¥15 通过安卓命令如何打开控制中心
      • ¥15 Nginx 配合Django 丢样式