自学内容网 自学内容网

原生js仿el-table动态表头

  • 解决动态表头数据量过大导致页面卡顿的问题
  • 解决固定前几列导致表头设置宽度失效或者错位的问题
  • 功能:
    • 固定前几列
    • 合并指定单元格
 <div class="tableJoint2">
   <div>
      <table id="tableData"></table>
    </div>
    <div>
      <table id="tableData-2"></table>
    </div>
  </div>
 renderTable(id, data, columns) {
     // 根据顺序写tableJoint2容器的高度
     let tableJoint2Height = [246, 400];
// id 第一个表格id   data 数据   columns 表头
    // 固定前几列需要拆分为两个表格
    // 第一个表头
      let columnsData = [];
     // 第二个表头
      let columnsData2 = [];
      // 一个页面有多个地方用,固定的前几列数量不同,做了判断
      if (id === "tableData") {
      // 第一个表格固定前两列
        columnsData = [...columns].slice(0, 2);
        // 大于2,把剩下的表头赋值给第二个表格
        if (columns.length > 2) {
          columnsData2 = [...columns].slice(2, columns.length);
        }
      }
      // js动态渲染两个table
      const table = document.getElementById(id);
      table.style.height = "100%";
      table.style["borderCollapse"] = "collapse";
      table.style["color"] = "#606266";
      table.style.width = "100%";
      // 第二个表格的id用第一个表格id+'-2'命名
      const table2 = document.getElementById(id + "-2");
      table2.style.height = "100%";
      table2.style["borderCollapse"] = "collapse";
      table2.style["color"] = "#606266";
      table2.style.width = "100%";
      this.$nextTick(() => {
        // 获取两个表格的父元素
        const tableJoint2 = document.getElementsByClassName("tableJoint2");
        for (let i = 0; i < tableJoint2.length; i++) {
        // 使用flex布局,使两个表格并列
          tableJoint2[i].style.display = "flex";
          tableJoint2[i].style.width = "100%";
          // 高度必须设置,
          tableJoint2[i].style.height =  tableJoint2Height[i] + "px";

          // divDoms获取两个表格中的直接div
          let divDoms = tableJoint2[i].querySelectorAll("div");
          for (let a = 0; a < divDoms.length; a++) {
            divDoms[a].style.height = "100%";
            if (a === 1) {
            // 加行向滚动
              divDoms[a].style.overflow = "auto";
              divDoms[a].style.flex = 1;
              // 第二个表格出现行向滚动条会导致两边行向数据位置偏差,如果table2的宽度大于父元素的宽度,重新设置第一个表格的高度-滚动条的高度
              let table2Copy = divDoms[a].querySelector("table");
              if (table2Copy.scrollWidth > divDoms[a].clientWidth) {
                table.style.height = table.clientHeight - 3 + "px";
              }
            }
          }
        }
      });

      let tableHead = "<thead><tr>";
      let tableHead2 = "<thead><tr>";
      let tableBody = "<tbody>";
      let tableBody2 = "<tbody>";

      // 生成表头
      columnsData.forEach((column) => {
      // 表头样式根据需求写
        tableHead += `<th style="background:#eeeeee;color:'#333';fontSize:14px;font-weight:400 !important;border:1px solid #ebeef5;padding:0 50px;height:30px;white-space:nowrap"><span>${column.label}</span></th>`;
      });
      columnsData2.forEach((column) => {
      // 表头样式根据需求写
        tableHead2 += `<th style="background:#eeeeee;color:'#333';fontSize:14px;font-weight:400 !important;border:1px solid #ebeef5;padding:0 50px;height:30px;white-space:nowrap"><span>${column.label}</span></th>`;
      });
      tableHead += "</tr></thead>";
      tableHead2 += "</tr></thead>";
      // 生成表身 promptMessage
      data.forEach((row, index) => {
        tableBody += "<tr>";
        tableBody2 += "<tr>";
        columnsData.forEach((column) => {
        // 单元格数据和样式
          // data-index和data-date是给点击事件传值,属性为index和date
          tableBody += `
 <td data-index=${index} data-date=${
            column.label
          }  style="border:1px solid #ebeef5;text-align:${
            column.align || "center"
          };padding:0 10px;height:30px;white-space:nowrap;color:"#606266"">
${row[column.prop] || "--"}
</td>`;
        });
        columnsData2.forEach((column) => {
        // 单元格数据和样式
          tableBody2 += `
 <td data-index=${index} data-date=${
            column.label
          }  style="border:1px solid #ebeef5;text-align:${
            column.align || "center"
          };padding:0 10px;height:30px;white-space:nowrap;color:"#606266"">
${row[column.prop] || "--"}
</td>`;
        });
        tableBody += "</tr>";
        tableBody2 += "</tr>";
      });
      // 插入表头和表身到表格中
      table.innerHTML = `${tableHead}${tableBody}</tbody>`;
      table2.innerHTML = `${tableHead2}${tableBody2}</tbody>`;
      // 点击事件
       let tbody = table.querySelectorAll('tbody')[0]
            let tbodyTr = tbody.querySelectorAll('tr')
            for (let i = 0; i < tbodyTr.length; i++) {
                let td = tbodyTr[i].querySelectorAll('td')
                for (let j = 0; j < td.length; j++) {
                    td[j].addEventListener('click', (event) => {
                        // 获取传递过来的值
                        let td = event.target
                        let flg = td.getAttribute('data-flg')
                        let index = Number(td.getAttribute('data-index'))
                        let date = td.getAttribute('data-date')
                        console.log(date)
                    })
                }
            }
             this.$nextTick(() => {
                this.mergeFunc(id)
            })
    },
   //合并相同行
        mergeFunc(tableId) {
            if(tableId === 'myTable2') return
            var tab = document.getElementById(tableId);
            var maxCol = 3;//maxcol用于设置需要合并的列数
            var count, start;
            for (var col = maxCol - 1; col >= 0; col--) {
                //用于存储相同个数
                count = 1;
                for (var i = 0; i < tab.rows.length; i++) {
                    if (i > 0 && col > 0 && tab.rows[i].cells[col].innerHTML == tab.rows[i - 1].cells[col].innerHTML
                        && tab.rows[i].cells[col - 1].innerHTML == tab.rows[i - 1].cells[col - 1].innerHTML) {
                        count++;
                    } else if (i > 0 && col == 0 && tab.rows[i].cells[col].innerHTML == tab.rows[i - 1].cells[col].innerHTML) {
                        count++;
                    } else {
                        if (count > 1) {
                            //合并
                            start = i - count;
                            tab.rows[start].cells[col].rowSpan = count;
                            for (var j = start + 1; j < i; j++) { //
                                tab.rows[j].removeChild(tab.rows[j].cells[col]);
                            }
                            count = 1;
                        }
                    }
                }
                if (count > 1) { //合并,最后几行相同的情况下
                    start = i - count;
                    tab.rows[start].cells[col].rowSpan = count;
                    for (var j = start + 1; j < i; j++) {
                        tab.rows[j].removeChild(tab.rows[j].cells[col]);
                    }
                }
            }
        },

原文地址:https://blog.csdn.net/qq_40673860/article/details/144303390

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!