JavaScript合并单元格【解决只能根据单列进行合并的问题】

在网上找到一个合并单元格的方法,但是发现有部分缺陷:不能够根据其他列进行对应合并。

这里自己创建了一个表格例子:

<table width="80%" border="1" cellpadding="0" cellspacing="0">
      <thead>
        <tr>
            <td colspan="5" class="maintit">成绩表</td>
        </tr>
        <tr>
            <td>姓名</td>
            <td>性别</td>
            <td>年龄</td>
            <td>科目</td>
            <td>分数</td>
        </tr>
    </thead>
    <tbody id="tab">
      <tr>  
        <td>张三 </td>  
        <td></td>  
        <td>21</td>  
        <td>数学 </td>  
        <td>90 </td>  
      </tr>  
      <tr>  
        <td>张三 </td>  
        <td></td>  
        <td>21</td>  
        <td>语文 </td>  
        <td>70 </td>  
      </tr>  
      <tr>  
        <td>张三 </td>  
        <td></td>  
        <td>21</td>  
        <td>英语 </td>  
        <td>60 </td>  
      </tr>  
      <tr>  
        <td>张三 </td>  
        <td></td>  
        <td>21</td>  
        <td>英语 </td>  
        <td>61 </td>  
      </tr>  
      <tr>  
        <td>张三 </td>  
        <td></td>  
        <td>21</td>  
        <td>英语 </td>  
        <td>62 </td>  
      </tr>  
      <tr>  
        <td>李四 </td>  
        <td></td>  
        <td>21</td>   
        <td>数学 </td>  
        <td>60 </td>  
      </tr>  
      <tr>  
        <td>李四 </td>  
        <td></td>  
        <td>21</td>   
        <td>语文 </td>  
        <td>60 </td>  
      </tr>  
      <tr>  
        <td>李四 </td>  
        <td></td>  
        <td>21</td>   
        <td>语文 </td>  
        <td>61 </td>  
      </tr>    
      <tr>  
        <td>李四 </td>  
        <td></td>  
        <td>21</td>   
        <td>语文 </td>  
        <td>62 </td>  
      </tr>    
      <tr>  
        <td>李四 </td>  
        <td></td>  
        <td>21</td>   
        <td>语文 </td>  
        <td>60 </td>  
      </tr>   
      <tr>  
        <td>王五 </td>  
        <td></td>  
        <td>21</td>   
        <td>英语 </td>  
        <td>60 </td>  
      </tr>
      <tr>  
        <td>王五 </td>  
        <td></td>  
        <td>21</td>   
        <td>语文 </td>  
        <td>60 </td>  
      </tr> 
      <tr>  
        <td>王五1 </td>  
        <td></td>  
        <td>21</td>   
        <td>英语 </td>  
        <td>60 </td>  
      </tr>   
      <tr>  
        <td>王五1 </td>  
        <td></td>  
        <td>21</td>   
        <td>英语 </td>  
        <td>66 </td>  
      </tr>  
      <tr>  
        <td>王五1 </td>  
        <td></td>  
        <td>21</td>   
        <td>数学</td> </td>  
        <td>60 </td>  
      </tr>
    </tbody> 
  </table> 

这是我在网上查询到的合并单元格的方法:

function mergeCell(table1, startRow, endRow, col) {
    var tb = document.getElementById(table1);
    if(!tb || !tb.rows || tb.rows.length <= 0) {
        return;
    }
    if(col >= tb.rows[0].cells.length || (startRow >= endRow && endRow != 0)) {
        return;
    }
    if(endRow == 0) {
        endRow = tb.rows.length - 1;
    }
    for(var i = startRow; i < endRow; i++) {
       if(tb.rows[startRow].cells[col].innerHTML == tb.rows[i + 1].cells[col].innerHTML) {
            tb.rows[i + 1].removeChild(tb.rows[i + 1].cells[col]);
            tb.rows[startRow].cells[col].rowSpan = (tb.rows[startRow].cells[col].rowSpan) + 1;
        } else {
            mergeCell(table1, i + 1, endRow, col);
            break;
        }
    }
}

// 合并单元格
setTimeout( function(){
	mergeCell('tab', 0, 0, 4);    // 合并第5列
  	mergeCell('tab', 0, 0, 3);	  // 合并第4列
  	mergeCell('tab', 0, 0, 2);    // 合并第3列
  	mergeCell('tab', 0, 0, 1);    // 合并第2列
  	mergeCell('tab', 0, 0, 0);    // 合并第1列
}, 500)

效果如下:
在这里插入图片描述

此时每列只能根据该列的重复值进行合并,看着比较混乱。

在该样式上增加需求:
1.姓名列之后的字段都能够根据姓名的不同进行分割。
2.分数字段还需要根据科目的不同进行分割。

更改了该方法如下:

/**
 * 合并单元格--封装完成(如果结束行传0代表合并所有行)
 * @param table1    表格的ID或类名
 * @param startRow  起始行
 * @param endRow    结束行
 * @param col   合并的列号,对第几列进行合并(从0开始)
 * @param dyCol   对应的列号[arr],需要根据哪些列对齐”
 */
function mergeCell(table1, startRow, endRow, col, dyCol) {
		//此处用了querySelector,可以根据需求使用id名或类名
    var tb = document.querySelector(table1);
    if(!tb || !tb.rows || tb.rows.length <= 0) {
        return;
    }
    if(col >= tb.rows[0].cells.length || (startRow >= endRow && endRow != 0)) {
        return;
    }
    if(endRow == 0) {
        endRow = tb.rows.length - 1;
    }
    for(var i = startRow; i < endRow; i++) {
        if(tb.rows[startRow].cells[col].innerHTML == tb.rows[i + 1].cells[col].innerHTML){
            // 定义条件
            var flag = "";
            for(var j=0; j<dyCol.length; j++){
                flag += " tb.rows[startRow].cells["+ dyCol[j] +"].innerHTML == tb.rows[i + 1].cells["+ dyCol[j] +"].innerHTML &&"
            }
            // 去除 &&
            flag = flag.slice(1,-3);

            // 必须加eval(),否则flag会被当做true传入if条件里
            if(eval(flag)){
                tb.rows[i + 1].removeChild(tb.rows[i + 1].cells[col]);
                tb.rows[startRow].cells[col].rowSpan = (tb.rows[startRow].cells[col].rowSpan) + 1;
            }else {
                mergeCell(table1, i + 1, endRow, col, dyCol);
                break;
            }
        }else {
            mergeCell(table1, i + 1, endRow, col, dyCol);
            break;
        }
    }
}

// 合并单元格
setTimeout( function(){
    mergeCell('#tab', 0, 0, 4, [3,0]);   // 根据第四列和第一列合并第5列
    mergeCell('#tab', 0, 0, 3, [0]);     // 根据第一列合并第4列
    mergeCell('#tab', 0, 0, 2, [0]);     // 根据第一列合并第3列
    mergeCell('#tab', 0, 0, 1, [0]);     // 根据第一列合并第2列
    mergeCell('#tab', 0, 0, 0, [0]);     // 根据第一列合并第1列
}, 500)

效果如下:
在这里插入图片描述

通过两个图片的对比,下方可以看出整齐了许多~
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值