赞
踩
第一步,给表格添加事件
- export var finalCollsArr = null // 用来存放单元格的id数组
- let flag = false// 当鼠标被按下时,为true,放开是为true
- let indexs = []// 用来存放鼠标经过的单元格在整个表格的位置,鼠标按下时被初始化,
- table.addEventListener('mousedown', (e) => {
- getTbList(table) // 获取表格的单元格id
- if (e.button == 0) {
- flag = true
- indexs = []
- }
-
-
- }, false)
-
- tableNode.addEventListener('mousemove', (e) => {
- if (flag) { // 只有鼠标被按下时,才会执行复合代码
- search(e.target, indexs)
- }
- }, false)
-
- tableNode.addEventListener('mouseup', () => {
- flag = false
- finalCollsArr = collsDistribute(indexs)
-
- }, false)
第二步:获取单元格在表格中id分布,获取鼠标选中的单元格id分布
- // 整个单元格的id分布,在删除行列,插入行列中有使用到
- export var list = new Array()
-
- /**
- * 获取单元格id
- * @param {表格节点} curTable
- */
- export const getTbList = (curTable) => {
- if (!curTable) {
- return
- }
- const rowLength = curTable.rows.length
- const colLength = getCellLength(curTable)
- // let arr = new Array(colLength).fill('undefined');
- // list = new Array(rowLength).fill(arr);
- list = new Array()
- for (let i = 0; i < rowLength; i++) {
- let arr = []
- for (let j = 0; j < colLength; j++) {
- arr.push('undefined')
- }
- list.push(arr)
- }
-
- let rowNum = 0;
- let colNum = 0
-
- for (let i = 0; i < rowLength; i++) {
- for (let j = 0; j < colLength; j++) {
- // 获取单元格
- let tdNode = curTable.rows[rowNum].cells[colNum]
- if (!tdNode) {
- continue
- }
- for (let k = j; k < colLength; k++) {
- if (list[i][k] != 'undefined' ) {
- continue
- }
- list[i][k] = tdNode.getAttribute('id')
- j = k;
- break
- }
-
- let rowspan = tdNode.rowSpan
- let colspan = tdNode.colSpan
-
-
- if (rowspan>1 && colspan>1) {
- for (let k = 0; k < rowspan; k++) {
- for (let z = 0; z < colspan; z++) {
- list[i+k][j+z] = tdNode.getAttribute('id')
- }
- }
- }else if(rowspan>1 || colspan>1){
- for (let k = 0; k < rowspan; k++) {
- list[i+k][j] = tdNode.getAttribute('id')
- }
- for (let k = 0; k < colspan; k++) {
- list[i][j+k] = tdNode.getAttribute('id')
- }
- }
- colNum++;
- }
- rowNum++;
- colNum = 0;
- }
- console.log("list: ", list);
- // 第一行 id
- oneRowId = list[0];
- let newArray = list[0].map(function (col, i) {
- return list.map(function (row) {
- return row[i]
- })
- })
- // 第一列 id
- oneColId = newArray[0]
- }
-
-
- /**
- * 将鼠标经过的单元格添加到数组
- * @param {单元格} tdNode
- * @param {数组} indexs
- * @returns
- */
- export const search = (tdNode, indexs) => {
- if (tdNode.getAttribute('tagname') != 'entry') {
- return
- }
- let id = tdNode.getAttribute('id')
- let ind = indexs.indexOf(id)
- if (ind == -1) {
- // 不存在
- indexs.push(id)
- } else if (ind != -1 && ind != indexs.length - 1) {
- indexs.splice(ind, 1)
- }
- }
-
- /**
- * 获取鼠标选中的单元格分布
- * @param {数组} indexs
- */
- export const collsDistribute = (indexs) => {
- let collsArr = new Array()
- let firstId = indexs[0]
- let endId = indexs[indexs.length-1]
- let arrRow = new Array();
- let arrCol = new Array();
- // 获取id在list数组的第几行第几列
- let row = 0
- let col = 0
- for (let i = 0; i < list.length; i++) {
-
- list[i].forEach((id,index)=>{
- if(id === firstId){
- arrRow[row++] = i
- arrCol[col++] = index
- }
- });
-
- list[i].forEach((id,index)=>{
- if(id === endId){
- arrRow[row++] = i
- arrCol[col++] = index
- }
- });
- }
- arrRow.sort()
- arrCol.sort()
-
- let minCols = Math.min(arrCol[0], arrCol[arrCol.length-1])
- let maxCols = Math.max(arrCol[0], arrCol[arrCol.length-1])
- let minRows = Math.min(arrRow[0], arrRow[arrRow.length-1])
- let maxRows = Math.max(arrRow[0], arrRow[arrRow.length-1])
- let x = maxRows-minRows+1
- let y = maxCols-minCols+1
-
- for (let i = 0; i < x; i++) {
- let arr = []
- for (let j = 0; j < y; j++) {
- arr.push('false')
- }
- collsArr.push(arr)
- }
- // let arr = new Array(y).fill('false')
- // let collsArr = new Array(x).fill(arr)
-
- for (let i = 0; i < x; i++) {
- console.log("minRows: " + minRows);
- for (let j = 0; j < y; j++) {
- console.log("minCols: " + minCols);
- collsArr[i][j] = list[minRows][minCols++]
- if (minCols>maxCols) {
- break
- }
- }
- minCols = maxCols + 1 - y
- minRows++
- if (minRows>maxRows) {
- break
- }
- }
-
- // console.log("===================");
- // console.log(collsArr);
-
- return collsArr;
-
- }
-
- /**
- * 获取表格的列数
- * @param {表格节点} curTable
- * @returns
- */
- export const getCellLength = (curTable) => {
- let rowNode = curTable.rows[0]
- let tdNodeList = rowNode.getElementsByTagName('td')
- let length = 0
- for (let i = 0; i < tdNodeList.length; i++) {
- let rowspan = tdNodeList[i].getAttribute('colspan')
- if (rowspan) {
- length += Number(rowspan)
- } else {
- length++
- }
- }
- return length
- }
-
- /**
- * 获取单元格所在的列数
- * @param {单元格} td
- * @param {列数组} arr
- */
- export const getCellsTrain = (td, arr) => {
-
- let id = td.getAttribute('id')
-
- // 列位置
- let col = -1
- for (let i = 0; i < arr.length; i++) {
- if(arr[i].indexOf(id) != -1){
- col = i
- break
- }
- }
-
- return col
- }
-
第三步:合并单元格
- /**
- * 合并单元格
- * @param {单元格id数组,第一步中的finalCollsArr} arr
- */
- export const mergeCells = (arr) => {
-
- // 获取行列值最小的单元格
- let id = arr[0][0]
- let td = document.getElementById(id)
- // 行和列
- let colspan = arr[0].length
- let rowspan = arr.length
- td.setAttribute('colspan', colspan)
- td.setAttribute('rowspan', rowspan)
-
- for (let i = 0; i < rowspan; i++) {
- for (let j = 0; j <colspan; j++) {
-
- // 相同的id跳过
- if (arr[i][j] == id) {
- continue
- }
- let delColls = document.getElementById(arr[i][j])
- // 不存在的单元格跳过
- if (!delColls) {
- continue
- }
- // 删除单元格
- delColls.parentNode.removeChild(delColls)
- }
- }
- }
第四步:插入行
- /**
- * 插入行
- * @param {单元格} colls
- * @param {表格} curTable
- * @param {true:向上插入, false:向下插入} isUp
- */
- export const addRow = (colls, curTable, isUp) => {
-
- // 获取单元格所在行数
- let row = colls.parentNode.rowIndex; // 行位置
- let rowNode = colls.parentNode // 行节点
- // 获取总列数
- let cellLength = getCellLength(curTable)
-
- let arrId = list[row]
-
- // 判断上(下)一行有没有这一行的元素
- // 在第一行上方插入和在最后一行下方插入就不用判断
-
- if (!((isUp && row == 0) || (!isUp && row == list.length-1))) {
- let arr = isUp ? list[row-1] : list[row+1]
- let redoArr = []
- for (let i = 0; i < arrId.length; i++) {
- if (arrId[i] == arr[i]) {
- cellLength--
- if (redoArr.indexOf(arrId[i]) == -1) {
- redoArr.push(arrId[i])
- }
- }
- }
-
- for (let i = 0; i < redoArr.length; i++) {
- let td = document.getElementById(redoArr[i])
- let rowspan = td.rowSpan
- td.rowSpan = rowspan + 1
- }
- }
-
- const trNode = document.createElement('tr')
- trNode.setAttribute("tagname", "row"); // 设置属性
- trNode.setAttribute("id", `tag_${global.id}`);
- global.id = global.id + 1
-
- let tdHtml = ''
- for (let j = 0; j < cellLength; j++) {
- tdHtml += `<td tagname='entry' id='tag_${global.id}' style="padding: 8px; line-height: 1.42857; vertical-align: top; border: 1px solid rgb(221, 221, 221);"> </td>`
- global.id = global.id + 1
- }
- trNode.innerHTML = tdHtml
- if (isUp) {
- rowNode.parentNode.insertBefore(trNode, rowNode)
- }else{
- rowNode.parentNode.insertBefore(trNode, rowNode.nextSibling)
- }
- }
第五步:插入列
- /**
- * 插入列
- * @param {单元格} colls
- * @param {true:向左插入, false:向右插入} isLeft
- * @returns
- */
- export const addCell = (colls, isLeft) => {
-
- // const rowLength = curTable.rows.length // 行數量
-
- // 行转列
- let newArray = list[0].map(function (col, i) {
- return list.map(function (row) {
- return row[i]
- })
- })
- // 获取单元格所在的列
- let col = getCellsTrain(colls, newArray)
- if (col == -1) {
- return
- }
- // 这一列的id
- let arrId = newArray[col]
- let arr = []
- if (!((isLeft && col == 0) || (!isLeft && col == newArray.length-1))) {
- arr = isLeft ? newArray[col-1] : newArray[col+1]
- }
-
- let redoArr = []
-
- for (let i = 0; i < arrId.length; i++) {
- let td = document.getElementById(arrId[i])
-
- // 创建单元格节点
- let newCell = document.createElement('td')
- newCell.setAttribute("tagname", "entry")
- newCell.setAttribute("id", `tag_${global.id}`)
- global.id = global.id + 1
- newCell.setAttribute("style", "padding: 8px; line-height: 1.42857; vertical-align: top; border: 1px solid rgb(221, 221, 221);")
- newCell.innerHTML = ' '
-
- if (arr.length>0) {
- if (arr[i] == arrId[i]) {
- if (redoArr.indexOf(arrId[i]) == -1) {
- let colspan = td.colSpan
- td.colSpan = colspan + 1
- redoArr.push(arrId[i])
- }
- continue
- }
- let tdBro = document.getElementById(arr[i])
- if (Array.from(new Set(arrId)).length < arrId.length) {
- if (td.parentNode.rowIndex != tdBro.parentNode.rowIndex) {
- if (isLeft) {
- td = tdBro.nextSibling
- }else{
- td = tdBro.previousSibling
- }
- }
- }
-
- }else {
- if (td.parentNode.rowIndex != i) {
- if (col == 0) {
- td = document.getElementById(newArray[col + 1][i])
- td.parentNode.insertBefore(newCell, td)
- } else {
- td = document.getElementById(newArray[col - 1][i])
- td.parentNode.appendChild(newCell)
- }
- continue
- }
- }
-
- if (isLeft) {
- !td ? curTable.rows[i].appendChild(newCell) : td.parentNode.insertBefore(newCell, td)
- } else {
- td.parentNode.insertBefore(newCell, td.nextSibling)
- }
- }
-
- }
第六步:删除行
- // colls: 单元格节点, curTable:表格节点
- export const delRow = (colls, curTable) => {
- const rowLength = curTable.rows.length // 行數量
- if (rowLength < 2) {
- alert('不能全部删除!')
- return
- }
- let row = colls.parentNode.rowIndex; // 行位置
- // let col = colls.cellIndex; // 列位置
-
- let rowNode = colls.parentNode // 行节点
- let tdNodeList = rowNode.getElementsByTagName('td')
-
- // 遍历这一行的单元格有没有跨行的, 如果跨行就将下一行的这一列的单元格跨行-1,相同跨列
- for (let i = 0; i < tdNodeList.length; i++) {
- let rowspan = tdNodeList[i].rowSpan
- if (rowspan>1) {
- let colspan = tdNodeList[i].colSpan
- let rowChild = curTable.rows[row+1]
- let colChild = rowChild.cells[i]
- let newCell = document.createElement('td')
- newCell.setAttribute("tagname", "entry")
- newCell.setAttribute("id", `tag_${global.id}`)
- global.id = global.id + 1
- newCell.setAttribute("rowspan", rowspan-1)
- newCell.setAttribute("colspan", colspan)
- newCell.setAttribute("style", "padding: 8px; line-height: 1.42857; vertical-align: top; border: 1px solid rgb(221, 221, 221);")
- newCell.innerHTML = ' '
- rowChild.insertBefore(newCell, colChild)
- }
- }
-
- // 遍历有没有被跨行的,将被跨行的跨行数-1
- let arrId = list[row]
- for (let i = 0; i < arrId.length; i++) {
- let td = document.getElementById(arrId[i])
- let tdRow = td.parentNode.rowIndex;
- if (row == tdRow) {
- continue
- }
- let rowNum = td.rowSpan
- td.rowSpan = rowNum -1
- }
-
- rowNode.parentNode.removeChild(rowNode)
-
- }
第七步:删除列
- // colls: 单元格节点, curTable:表格节点
- export const delCell = (colls, curTable) => {
-
- const cellLength = getCellLength(curTable)
- if (cellLength < 2) {
- alert('不能全部删除!')
- return
- }
-
- // 行转列
- let newArray = list[0].map(function (col, i) {
- return list.map(function (row) {
- return row[i]
- })
- })
- let col = getCellsTrain(colls, newArray)
- if (col == -1) {
- return
- }
-
- // 这一列的值
- let arrId = newArray[col]
-
- for (let i = 0; i < arrId.length; i++) {
- let td = document.getElementById(arrId[i])
- let tdCol = getCellsTrain(td, newArray)
- // 判断单元格有没有被跨列,有,将跨列的 跨列-1
- if (tdCol != col) {
- let colNum = td.colSpan
- td.colSpan = colNum -1
- continue
- }
- // 判断单元格有没有跨列,有跨列,在该单元格的后面添加一个单元格 跨列-1
- let colspan = td.colSpan
- if (colspan>1) {
- let tdNext = td.nextSibling
- let rowspan = td.rowSpan
- let newCell = document.createElement('td')
- newCell.setAttribute("tagname", "entry")
- newCell.setAttribute("id", `tag_${global.id}`)
- global.id = global.id + 1
- newCell.setAttribute("rowspan", rowspan)
- newCell.setAttribute("colspan", colspan-1)
- newCell.setAttribute("style", "padding: 8px; line-height: 1.42857; vertical-align: top; border: 1px solid rgb(221, 221, 221);")
- newCell.innerHTML = ' '
- td.parentNode.insertBefore(newCell, tdNext)
- }
-
- td.parentNode.removeChild(td)
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。