vue3 table 按住鼠标左键范围框选v1

javascript 复制代码
<template>
  startCell {{ startCell }}
  endCell {{ endCell }}

  <table border="1"
  id="cabinet_latte_table"
      align="center"
      width="50%"
      cellpadding="10"
      cellspacing="0"
  >
<tr v-for="(row, rindex) in tabaleData" :key="row.id" :id="rindex">

  
  <td
          :id="col.id"
          :initRow="rindex"
          :initCol="cindex"
          :col="JSON.stringify(col)"
          @mousedown="handleMouseDown"
          @mouseup="handleMouseUp"
  
  v-for="(col, cindex) in row" :key="col.id">
{{ col.name }}-{{ col.id }}-{{ cindex }}-{{ rindex }}

  </td>

</tr>

  </table>
  
</template>
<script setup>
import guid from '@/utils/generator'
import { reactive,ref,nextTick } from 'vue';
const dragging = ref(false)
const tableId = 'cabinet_latte_table'

let chooseCellsArea =reactive([])
let startCell = ref({})
let endCell = ref({})
const tabaleData = reactive([])
  //填充数据横纵
const addCell = () => {
  let colsNum = 5; 
  let datasNum = 7; 


  for(let i = 0;i<datasNum;i++) {
     
    let colsTemp = []
    for(let j = 0;j<colsNum;j++) {
      colsTemp.push(
        { name:'小明',type:'0',x:'',y:'',id:(i*colsNum)+j+'' }
      );
    }
    tabaleData.push(colsTemp)
  }

  console.log('tabaleData ', tabaleData)

}

    const isOkRang = (initRow,initCol,startRow,startCol,endRow,endCol) =>{
          return (initRow >= startRow && initRow <= endRow && initCol >= startCol && initCol <= endCol) 
        //  ||(initRow >= endRow && initRow <= startRow && initCol >= endCol && initCol <= startCol)
    }


        // 获取范围并且将改变边框颜色
    const    applyBorderStyles = (tableId, startRow, startCol, endRow, endCol) => {
      clearBorderStyles(tableId)
      const cellList = document.getElementById(tableId).querySelectorAll('td')
      
      //   let endRowNum = endRow;
      //   let endColNum = endCol;
      const cellsInRange = []
      const cellsIdsRange = []
      cellList.forEach((cell) => {
        //遍历所有的td,在那个开始和当前停留位置的td的范围内的都设置选中样式 huang
        const initRow = parseInt(cell.getAttribute('initrow'), 10)
        const initCol = parseInt(cell.getAttribute('initcol'), 10)
        // 判断单元格是否在指定范围内
       // if (initRow >= startRow && initRow <= endRow && initCol >= startCol && initCol <= endCol) {
        if (isOkRang(initRow,initCol,startRow,startCol,endRow,endCol)) {
          // console.log('我看真正添加的 initRow ',initRow)
          // console.log('我看真正添加的 initCol ',initCol)
          cellsInRange.push(cell)

          chooseCellsArea = cellsInRange

          cell.style.backgroundColor = '#c0bfbf'
          // 应用顶部边框样式
          if (initRow === startRow) {
            cell.style.borderTop = '2px solid #409eff'
          }

          // 应用底部边框样式
          if (initRow === endRow) {
            cell.style.borderBottom = '2px solid #409eff'
          }

          // 应用左侧边框样式
          if (initCol === startCol) {
            cell.style.borderLeft = '2px solid #409eff'
          }

          // 应用右侧边框样式
          if (initCol === endCol) {
            cell.style.borderRight = '2px solid #409eff'
          }
        }
      })
      //console.log('选中的单元格', chooseCellsArea)
    }
    


const clearBorderStyles = (tableId) => {
      const rowList = document.getElementById(tableId).querySelectorAll('tr')
      if (!rowList) return

      // 遍历所有行和单元格,清除边框样式
      for (const row of rowList) {
        for (const cell of row.cells) {
          cell.style.borderTop = ''
          cell.style.borderBottom = ''
          cell.style.borderLeft = ''
          cell.style.borderRight = ''
          cell.style.backgroundColor = 'transparent'
        }
      }
    }
addCell()
const handleMouseDown=(event) =>{

      nextTick(()=>{
        if (event.button === 0) {
          dragging.value = true

          // 获取起始单元格信息,这里可能需要一些逻辑来确定单元格的行和列
          const target = event.currentTarget
          if (target) {
            console.log('摁下initrow.value ',target.attributes.initrow.value)
            console.log('摁下initcol.value ',target.attributes.initcol.value)
            const row = Number(target.attributes.initrow.value)
            const col = Number(target.attributes.initcol.value)
            const cellId = target.id
            //记录左键点击开始位置 huang
            startCell.value = { cellId, row, col }
            console.log('按完了 加里没有', startCell.value);
          }

          // 添加全局鼠标移动事件监听
          window.addEventListener('mousemove', handleMouseMove)
        }
    })

    }
    const   handleMouseUp=(event) => {
      dragging.value = false

      // 移除全局鼠标移动事件监听
      window.removeEventListener('mousemove', handleMouseMove)
    }

    const   handleMouseMove = (event) => {
      //   if (!this.dragging) {
      //     return;
      //   }
      //   console.log('的高亮显示');
      // 这里可以根据需要添加逻辑,例如更新当前单元格的高亮显示
      nextTick(() => {})
      if (event.button === 0) {
        //当前鼠标位置的组件
        const { target } = event
        // console.log('target.parentNode', event);
        if (target) {
          //当前鼠标位置的行数 huang
          const row = Number(target.attributes.initrow.value)
          //当前鼠标位置的列数 huang
          const col = Number(target.attributes.initcol.value)



          clearBorderStyles(tableId)
          applyBorderStyles(tableId, startCell.value.row, startCell.value.col, row, col,target.id)
        }
      }
    }







  

</script>

<style lang="scss" scoped>

table  {
  -moz-user-select: none;
  -webkit-user-select: none;
  -ms-user-select: none;
  -khtml-user-selece: none;
  /*上面都是兼容性问题,具体看浏览器版本或什么浏览器*/
  user-select: none;
}
  </style>
相关推荐
一个处女座的程序猿O(∩_∩)O2 小时前
小型 Vue 项目,该不该用 Pinia 、Vuex呢?
前端·javascript·vue.js
燃先生._.8 小时前
Day-03 Vue(生命周期、生命周期钩子八个函数、工程化开发和脚手架、组件化开发、根组件、局部注册和全局注册的步骤)
前端·javascript·vue.js
高山我梦口香糖9 小时前
[react]searchParams转普通对象
开发语言·前端·javascript
black^sugar10 小时前
纯前端实现更新检测
开发语言·前端·javascript
ThreeYear_s11 小时前
基于FPGA 的4位密码锁 矩阵键盘 数码管显示 报警仿真
fpga开发·矩阵·计算机外设
2401_8576009511 小时前
SSM 与 Vue 共筑电脑测评系统:精准洞察电脑世界
前端·javascript·vue.js
2401_8576009511 小时前
数字时代的医疗挂号变革:SSM+Vue 系统设计与实现之道
前端·javascript·vue.js
GDAL11 小时前
vue入门教程:组件透传 Attributes
前端·javascript·vue.js
小白学大数据11 小时前
如何使用Selenium处理JavaScript动态加载的内容?
大数据·javascript·爬虫·selenium·测试工具