• 使用jquery扩展表格行合并方法探究


    1.前言

      最近项目中用到一个表格中对于相同内容的数据进行行合并的需求,本来想从网上找个现成的,省的自己再造轮子.于是就开始谷歌了...不过在搜索的过程中,发现找到的工具类很多都有一个前提,就是该表格中还没有行合并的单元格,即没有rowspan属性的的简单表格.那么我的问题来了,如果我的表格不是一个简单的表格呢,或者说我按照某一列合并之后,继续想合并其他列该如何处理呢.继续谷歌...(在此没有跟谷歌打广告的意思谢谢).没办法,自己造轮子吧.

    2.简单的想法

      如果才能获取某个表格的某一列数据呢,在此不能想当然的把表格想象成简单的表格,我需要造一个尽可能通用一点的轮子.

    1 $("td:nth-child(" + trIndex + ")")

    通过上面的代码,(其中trIndex代表某一列的索引)可以得到相同列索引的单元格.but,有个前提,表格中没有rowspan属性,更加准确的说没有rowspan值大于1的单元格.那么我想造通用轮子的方法,目前而言不能使用这个方法了,不过这个代码放这里,以后还有用处.

    3.基本分析

      现在分析一下对于一个5行5列表格中已经存在行合并的单元格该如何处理呢?比如第一行,第一个单元有个属性rowspan=2,表示的含义不用我来说了,那么jquery取如何理解呢,jquery会这么想,第一行有5个单元格,第二行有4个单元格.如下面的表格.此时第二行的第一个单元格时'67890'.可以这么理解,从有属性rowspan>1的单元格列索引以后的下几行数据的列索引都会发生变化.稍微有些难理解,即标记为红色的这一行单元格的列索引都会发生变化.

    12345
    67890 12345 67890 12345
    67890 12345 67890 12345
    12345 67890 12345 67890 12345
    12345 67890 12345 67890 12345
    12345 67890 12345 67890 12345

      既然可以认识到这一点,那么我们的工作就完成一半了,剩下要做的就是把列索引由于行合并属性造成的错位修复回去,这样我们就可以使用上面的代码代码获取某一列的所有单元格,进而合并单元格中相同内容了.首先我自定义了一个属性rowspanMark,用来标记需要修正的单元格,以及修正的数目,比如说,第二行第一列'67890'所在这行,本来列索引应该是1,但是由于第一行第一列行合并导致,这一行的索引变成了0,那么就在这一单元上的rowspanMark标记成1,加上列索引0,即修正为真正的列索引.好了,原理讲清楚了,直接上代码,代码中也有注释,不清楚的可以留言.

      1 (function ($) {
      2     /**
      3      *  标记所有rowspan之后导致其后的单元格cellindex减少的现象.
      4      */
      5     $.fn.addRowspanMark = function () {
      6         this.each(function () {
      7             $(this).find("tbody tr").each(function (trIndex) {
      8                 trIndex = trIndex + 1;
      9                 //从index=0开始查找
     10                 // :nth-child从1开始的
     11                 $("td:nth-child(" + trIndex + ")").each(function (tdIndex, tdItem) {
     12                     var temp = tdItem;
     13                     //按照列的顺序找到所有的rowspan属性的单元格
     14                     var rowspanCount = $(tdItem).attr("rowspan");
     15                     //如果单元格属性rowspan大于则说明该单元格有合并同列下面的单元格
     16                     if (rowspanCount > 1) {
     17                         //修正当前rowspan属性大于的单元格在所在行的索引值
     18                         var tdItemIndexAmend = $(tdItem)[0].cellIndex + getRowspanMark($(tdItem));
     19                         //找到当前单元格的最近的父元素tr
     20                         var parent = $(tdItem).parent("tr")[0];
     21                         while (rowspanCount-- > 1) {
     22                             //依次处理当前单元格以下的单元
     23                             parent = $(parent).next();
     24                             //遍历tr中的所有单元格
     25                             $(parent).find("td").each(function (index, ele) {
     26                                 //修正当前单元格的索引值
     27                                 var curIndexAmend = index + getRowspanMark($(ele));
     28                                 //当前单元格大于等于合并单元格时
     29                                 if (curIndexAmend >= tdItemIndexAmend) {
     30                                     //满足条件后重新修正符合条件单元格rowspanMark属性
     31                                     $(ele).attr("rowspanMark", getRowspanMark($(ele)) + 1);
     32                                 }
     33                             });
     34                         }
     35                     }
     36                 });
     37             });
     38         });
     39     };
     40 
     41     /**
     42      * 删除所有rowspanMark标记.
     43      */
     44     $.fn.removeRowspanMark = function () {
     45         $(this).find("td").each(function (index, ele) {
     46             if ($(ele).attr("rowspanMark") != undefined) {
     47                 $(ele).removeAttr("rowspanMark");
     48             }
     49         });
     50     };
     51 
     52     /**
     53      * 合并行.
     54      * @param options
     55      *          [colIndex]  待合并列索引
     56      */
     57     $.fn.rowspan = function (options) {
     58         var defaults = {};
     59         options = $.extend(defaults, options);
     60 
     61         this.each(function () {
     62             //增加标记属性
     63             $(this).addRowspanMark();
     64 
     65             //遍历所有单元,找到经过修正后与参数中合并列索引相等的单元
     66             var tds = $(this).find("tbody td").filter(function () {
     67                 //找到标记
     68                 var rowspanMark = getRowspanMark($(this));
     69                 //找到当前单元格的列索引
     70                 var cellIndex = $(this)[0].cellIndex;
     71                 //重新修正
     72                 return rowspanMark + cellIndex == options.colIndex;
     73             });
     74 
     75             //暂存满足条件的第一个元素
     76             var current_td = tds.eq(0);
     77             //遍历
     78             tds.each(function (index) {
     79                 //上一元素与当前元素内容相同则进行合并
     80                 if ($(this).text() == current_td.text() && index != 0) {
     81                     //计算当前元素的rowspan
     82                     var thisSpan = getRowspan($(this));
     83                     //计算上一个元素的rowspan
     84                     var currentTdSpan = getRowspan(current_td);
     85                     //删除该元素
     86                     $(this).remove();
     87                     //将上一元素rowspan设置为两个元素的和
     88                     current_td.attr("rowspan", currentTdSpan + thisSpan);
     89                 } else {
     90                     //不满足条件继续遍历
     91                     current_td = $(this);
     92                 }
     93             });
     94 
     95             //删除标记属性
     96             $(this).removeRowspanMark();
     97         });
     98 
     99     };
    100 
    101     /**
    102      * 获取当前元素的rowspanMark值
    103      */
    104     function getRowspanMark(ele) {
    105         return ele.attr('rowspanMark') == undefined ? 0 : parseInt(ele.attr('rowspanMark'));
    106     }
    107 
    108     /**
    109      * 获取当前元素的rowspanMark值
    110      */
    111     function getRowspan(ele) {
    112         return ele.attr('rowspan') == undefined ? 1 : parseInt(ele.attr('rowspan'));
    113     }
    114 })(jQuery);

    末了,加上适用方式:代码中的0表示待合并的列索引

    1 $("#mergeTable").rowspan({colIndex: 0});

        最后多唠叨一句,记得加上jquery的包,本来这个方法是扩展jquery方法.另外,该方法只适用行合并,不适用列合并.有时间再研究列合并.

      感谢大家阅读,希望我的共享可以为你提供些许帮助.如有bug,请留言,谢谢

  • 相关阅读:
    开学第二周java作业暨动手动脑p1
    开学第一周
    暑假第九周
    暑假第八周
    bzoj4033:[HAOI2015]树上染色
    bzoj4472:[Jsoi2015]salesman
    dp专题复习
    bzoj1864:[Zjoi2006]三色二叉树
    bzoj1190:[HNOI2007]梦幻岛宝珠
    bzoj2794:[Poi2012]Cloakroom
  • 原文地址:https://www.cnblogs.com/geyifan/p/3434410.html
Copyright © 2020-2023  润新知