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

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日

悬赏问题

  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!
  • ¥15 drone 推送镜像时候 purge: true 推送完毕后没有删除对应的镜像,手动拷贝到服务器执行结果正确在样才能让指令自动执行成功删除对应镜像,如何解决?
  • ¥15 求daily translation(DT)偏差订正方法的代码
  • ¥15 js调用html页面需要隐藏某个按钮