获取 table 所有单元格的行列号,含合并单元格,行列号纠正


/**
 * 获取单元格修正后的x坐标位置
 * @param {Array} tdsPos - 存储单元格信息的二维数组
 * @param {number} rowIndex - 行索引
 * @param {number} columnIndex - 列索引
 * @returns {Object} - 修正后的x坐标位置
 */
function getTdRealPosX(tdsPos, rowIndex, columnIndex) {
  let colspanOffset = 0
  const currentTdPos = tdsPos[rowIndex][columnIndex]
  let flagNum = 0

  if (columnIndex !== 0) {
    const previousTdPos = tdsPos[rowIndex][columnIndex - 1]
    flagNum = previousTdPos.pos.x + previousTdPos.colspan - 1
  }

  for (let i = rowIndex; i >= 0; i--) {
    const rowCols = tdsPos[i]
    for (let j = 0; j < rowCols.length; j++) {
      const col = rowCols[j]
      if (i === rowIndex && j < columnIndex) {
        // 同一行单元格对后面单元格x坐标影响
        colspanOffset += col.colspan
      } else if (i < rowIndex && col.rowspan + i - 1 >= rowIndex) {
        if (
          col.pos.x + col.colspan - 1 <= flagNum ||
          colspanOffset === col.pos.x
        ) {
          // 上面单元格rowspan对x坐标的影响
          colspanOffset += col.colspan
        }
      }
    }
  }

  if (colspanOffset > 0) {
    console.log(`单元格 ${currentTdPos.title} 向右偏移 ${colspanOffset}`)
  }

  return { x: colspanOffset, y: rowIndex }
}

/**
 * 获取单元格修正后的坐标位置
 * @param {HTMLElement} trParent - tbody元素
 * @returns {Array} - 修正后的单元格位置二维数组
 */
function getRealPos(trParent) {
  const tdsPos = []
  const trs = trParent.children

  for (let i = 0; i < trs.length; i++) {
    const tr = trs[i]
    const tds = tr.children
    tdsPos[i] = []
    for (let j = 0; j < tds.length; j++) {
      const td = tds[j]
      const rowSpan = td.getAttribute('rowSpan') ? Number(td.getAttribute('rowSpan')) : 1
      const colSpan = td.getAttribute('colSpan') ? Number(td.getAttribute('colSpan')) : 1
      tdsPos[i][j] = {
        dom: td,
        title: td.innerHTML,
        rowspan: rowSpan,
        colspan: colSpan
      }
    }
  }

  // 逐个单元格坐标修复。修复顺序为从上到下,从左到右。即ABCDEFG。。。的顺序修复。
  tdsPos.forEach((rowCols, y) => {
    rowCols.forEach((col, x) => {
      col.pos = getTdRealPosX(tdsPos, y, x)
    })
  })

  return tdsPos
}

/**
 * 获取表格单元格信息
 * @param {HTMLElement} table - 表格元素
 * @returns {Object} - 包含单元格信息的对象
 */
export function getTableCells(table) {
  const tbody = table.querySelector('tbody')
  const tdsPos = getRealPos(tbody)
  const tableCells = {}

  // 填充 tableCells 对象
  tdsPos.forEach((row, rowIndex) => {
    tableCells[rowIndex] = {}
    row.forEach((cell, colIndex) => {
      tableCells[rowIndex][colIndex] = {
        dom: cell.dom,
        value: cell.dom.innerHTML,
        rowspan: cell.rowspan,
        colspan: cell.colspan,
        pos: {
          colIndex: cell.pos.x,
          rowIndex: cell.pos.y
        }
      }
    })
  })
  return tableCells
}

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

泡泡码客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值