zoukankan      html  css  js  c++  java
  • 合并table相同单元格的jquery插件(很精简)

    正好项目中有个小需求, 要求把表格指定列中内容相同的单元格进行合并,本质上涉及的就是td的rowspan属性, 数出含相同内容单元格的个数, 然后给第一个与上一行内容不同的td其rowspan属性附上正确的值即可, 为了能直观的理解, 效果如下

    原表格:

    col0 col1 col2 col3
    SuZhou 11111 22222 SuZhouCity
    SuZhou 33333 44444 SuZhouCity
    SuZhou 55555 66666 SuZhouCity
    ShangHai 77777 88888 ShangHaiCity
    ShangHai uuuuu hhhhh ShangHaiCity
    ShangHai ggggg ccccc ShangHaiCity
    GuangZhou ttttt eeeee GuangZhouCity
    GuangZhou ppppp qqqqq GuangZhouCity

    处理之后的样子:

    col0 col1 col2 col3
    SuZhou 11111 22222 SuZhouCity
    33333 44444
    55555 66666
    ShangHai 77777 88888 ShangHaiCity
    uuuuu hhhhh
    ggggg ccccc
    GuangZhou ttttt eeeee GuangZhouCity
    ppppp qqqqq

    效果出来, 看上去比较简单, 下面先看下页面

     1 <table id="process" cellpadding="2" cellspacing="0" border="1">
     2     <thead>
     3         <tr >
     4             <td>col0</td>
     5             <td>col1</td>
     6             <td>col2</td>
     7             <td>col3</td>
     8         </tr>
     9     </thead>
    10     <tbody>
    11         <tr>
    12             <td>SuZhou</td>
    13             <td>11111</td>
    14             <td>22222</td>
    15             <td>SuZhouCity</td>
    16         </tr>
    17         <tr>
    18             <td>SuZhou</td>
    19             <td>33333</td>
    20             <td>44444</td>
    21             <td>SuZhouCity</td>
    22         </tr>
    23         <tr>
    24             <td>SuZhou</td>
    25             <td>55555</td>
    26             <td>66666</td>
    27             <td>SuZhouCity</td>
    28         </tr>
    29         <tr>
    30             <td>ShangHai</td>
    31             <td>77777</td>
    32             <td>88888</td>
    33             <td>ShangHaiCity</td>
    34         </tr>
    35         <tr>
    36             <td>ShangHai</td>
    37             <td>uuuuu</td>
    38             <td>hhhhh</td>
    39             <td>ShangHaiCity</td>
    40         </tr>
    41         <tr>
    42             <td>ShangHai</td>
    43             <td>ggggg</td>
    44             <td>ccccc</td>
    45             <td>ShangHaiCity</td>
    46         </tr>
    47         <tr>
    48             <td>GuangZhou</td>
    49             <td>ttttt</td>
    50             <td>eeeee</td>
    51             <td>GuangZhouCity</td>
    52         </tr>
    53         <tr>
    54             <td>GuangZhou</td>
    55             <td>ppppp</td>
    56             <td>qqqqq</td>
    57             <td>GuangZhouCity</td>
    58         </tr>
    59     </tbody>
    60 </table>
    1 // 这里写成了一个jquery插件的形式
    2 $('#process').mergeCell({
    3     // 目前只有cols这么一个配置项, 用数组表示列的索引,从0开始 
    4     // 然后根据指定列来处理(合并)相同内容单元格
    5     cols: [0, 3]  
    6 });

    下面看看这个小插件的完整代码:

      1 <table id="process" cellpadding="2" cellspacing="0" border="1">
      2 <thead>
      3 <tr >
      4 <td>col0</td>
      5 <td>col1</td>
      6 <td>col2</td>
      7 <td>col3</td>
      8 </tr>
      9 </thead>
     10 <tbody>
     11 <tr>
     12 <td>SuZhou</td>
     13 <td>11111</td>
     14 <td>22222</td>
     15 <td>SuZhouCity</td>
     16 </tr>
     17 <tr>
     18 <td>SuZhou</td>
     19 <td>33333</td>
     20 <td>44444</td>
     21 <td>SuZhouCity</td>
     22 </tr>
     23 <tr>
     24 <td>SuZhou</td>
     25 <td>55555</td>
     26 <td>66666</td>
     27 <td>SuZhouCity</td>
     28 </tr>
     29 <tr>
     30 <td>ShangHai</td>
     31 <td>77777</td>
     32 <td>88888</td>
     33 <td>ShangHaiCity</td>
     34 </tr>
     35 <tr>
     36 <td>ShangHai</td>
     37 <td>uuuuu</td>
     38 <td>hhhhh</td>
     39 <td>ShangHaiCity</td>
     40 </tr>
     41 <tr>
     42 <td>ShangHai</td>
     43 <td>ggggg</td>
     44 <td>ccccc</td>
     45 <td>ShangHaiCity</td>
     46 </tr>
     47 <tr>
     48 <td>GuangZhou</td>
     49 <td>ttttt</td>
     50 <td>eeeee</td>
     51 <td>GuangZhouCity</td>
     52 </tr>
     53 <tr>
     54 <td>GuangZhou</td>
     55 <td>ppppp</td>
     56 <td>qqqqq</td>
     57 <td>GuangZhouCity</td>
     58 </tr>
     59 </tbody>
     60 </table>
     61 
     62 
     63 ;(function($) {
     64     // 看过jquery源码就可以发现$.fn就是$.prototype, 只是为了兼容早期版本的插件
     65     // 才保留了jQuery.prototype这个形式
     66     $.fn.mergeCell = function(options) {
     67         return this.each(function() {
     68             var cols = options.cols;
     69             for ( var i = cols.length - 1; cols[i] != undefined; i--) {
     70               // fixbug console调试
     71               // console.debug(cols[i]);
     72               mergeCell($(this), cols[i]);
     73             }
     74             dispose($(this));
     75         });
     76     };
     77     // 如果对javascript的closure和scope概念比较清楚, 这是个插件内部使用的private方法
     78     // 具体可以参考本人前一篇随笔里介绍的那本书
     79     function mergeCell($table, colIndex) {
     80 
     81         $table.data('col-content', ''); // 存放单元格内容
     82         $table.data('col-rowspan', 1);  // 存放计算的rowspan值  默认为1
     83         $table.data('col-td', $());     // 存放发现的第一个与前一行比较结果不同td(jQuery封装过的), 默认一个"空"的jquery对象
     84         $table.data('trNum', $('tbody tr', $table).length); // 要处理表格的总行数, 用于最后一行做特殊处理时进行判断之用
     85         
     86         // 我们对每一行数据进行"扫面"处理 关键是定位col-td, 和其对应的rowspan
     87         $('tbody tr', $table).each(function(index) {
     88             // td:eq中的colIndex即列索引
     89             var $td = $('td:eq(' + colIndex + ')', this);
     90 
     91             // 取出单元格的当前内容
     92             var currentContent = $td.html();
     93 
     94             // 第一次时走此分支
     95             if ($table.data('col-content') == '') {
     96 
     97                 $table.data('col-content', currentContent);
     98                 $table.data('col-td', $td);
     99 
    100             } else {
    101                 // 上一行与当前行内容相同
    102                 if ($table.data('col-content') == currentContent) {
    103                     // 上一行与当前行内容相同则col-rowspan累加, 保存新值
    104                     var rowspan = $table.data('col-rowspan') + 1;
    105                     $table.data('col-rowspan', rowspan);
    106                     // 值得注意的是  如果用了$td.remove()就会对其他列的处理造成影响
    107                     $td.hide();
    108 
    109                     // 最后一行的情况比较特殊一点
    110                     // 比如最后2行 td中的内容是一样的, 那么到最后一行就应该把此时的col-td里保存的td设置rowspan
    111                     if (++index == $table.data('trNum'))
    112                         $table.data('col-td').attr('rowspan', $table.data('col-rowspan'));
    113             
    114                 } else { // 上一行与当前行内容不同
    115                     // col-rowspan默认为1, 如果统计出的col-rowspan没有变化, 不处理
    116                     if ($table.data('col-rowspan') != 1) {
    117                         $table.data('col-td').attr('rowspan', $table.data('col-rowspan'));
    118                     }
    119                     // 保存第一次出现不同内容的td, 和其内容, 重置col-rowspan
    120                     $table.data('col-td', $td); 
    121                     $table.data('col-content', $td.html());
    122                     $table.data('col-rowspan', 1);
    123                 }
    124             }
    125         });
    126     }
    127     
    128     // 同样是个private函数  清理内存之用
    129     function dispose($table) {
    130         $table.removeData();
    131     }
    132 })(jQuery);

    主要的说明在注释里应该都有了, 代码的确比较简单, 像有些地方还值得改进

    • 处理的table内容是从tbody开始查找的, 如果没有tbody, 那应该给出个更通用化的方案

    • for ( var i = cols.length - 1; cols[i] != undefined; i--)...如果表格数据量大, 处理的列也比较多, 这里不进行优化会有造成浏览器线程阻塞的风险, 可以考虑用setTimeout

    • 其他什么值得改进的, 我想应该会不少的

  • 相关阅读:
    java中的各种Queue
    关闭线程的一些问题
    Exchanger
    文件锁FileLock
    StringBuffer和String需要注意的
    maven出现:Failed to execute goal on project ...: Could not resolve dependencies for project ...
    pringboot pom文件引入本地jar包和对其打jar包
    SpringBoot热部署的两种方式
    idea 自动导入包和自动将没用的包去除
    springCould:使用Feign 实现声明式服务调用
  • 原文地址:https://www.cnblogs.com/AndyWithPassion/p/table_merge.html
Copyright © 2011-2022 走看看