您的位置:首页 > Web前端 > JQuery

合并table相同单元格的jquery插件

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

原表格:

col0col1col2col3
SuZhou1111122222SuZhouCity
SuZhou3333344444SuZhouCity
SuZhou5555566666SuZhouCity
ShangHai7777788888ShangHaiCity
ShangHaiuuuuuhhhhhShangHaiCity
ShangHaigggggcccccShangHaiCity
GuangZhouttttteeeeeGuangZhouCity
GuangZhoupppppqqqqqGuangZhouCity
处理之后的样子:

col0col1col2col3
SuZhou1111122222SuZhouCity
3333344444
5555566666
ShangHai7777788888ShangHaiCity
uuuuuhhhhh
gggggccccc
GuangZhouttttteeeeeGuangZhouCity
pppppqqqqq
效果出来,看上去比较简单,下面先看下页面

viewsourceprint?

01
<
table

id
=
"process"

cellpadding
=
"2"

cellspacing
=
"0"

border
=
"1"
>
02
<
thead
>
03
<
tr

>
04
<
td
>col0</
td
>
05
<
td
>col1</
td
>
06
<
td
>col2</
td
>
07
<
td
>col3</
td
>
08
</
tr
>
09
</
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
>
viewsourceprint?

1
//这里写成了一个jquery插件的形式
2
$('#process').mergeCell({
3
//目前只有cols这么一个配置项,用数组表示列的索引,从0开始
4
//然后根据指定列来处理(合并)相同内容单元格
5
cols:[0,3]
6
});
下面看看这个小插件的完整代码:

viewsourceprint?

;(
function
($){
//看过jquery源码就可以发现$.fn就是$.prototype,只是为了兼容早期版本的插件
//才保留了jQuery.prototype这个形式
$.fn.mergeCell=
function
(options){
return

this
.each(
function
(){
var

cols=options.cols;
for

(
var
i=cols.length-1;cols[i]!=undefined;i--){
//fixbugconsole调试
//console.debug(cols[i]);
mergeCell($(
this
),cols[i]);
}
dispose($(
this
));
});
};
//如果对javascript的closure和scope概念比较清楚,这是个插件内部使用的private方法
//具体可以参考本人前一篇随笔里介绍的那本书
function

mergeCell($table,colIndex){
$table.data(
'col-content'
,
''
);

//存放单元格内容
$table.data(
'col-rowspan'
,1);
//存放计算的rowspan值默认为1
$table.data(
'col-td'
,$());
//存放发现的第一个与前一行比较结果不同td(jQuery封装过的),默认一个"空"的jquery对象
$table.data(
'trNum'
,$(
'tbodytr'
,$table).length);
//要处理表格的总行数,用于最后一行做特殊处理时进行判断之用
//我们对每一行数据进行"扫面"处理关键是定位col-td,和其对应的rowspan
$(
'tbodytr'
,$table).each(
function
(index)
{
//td:eq中的colIndex即列索引
var

$td=$(
'td:eq('

+colIndex+
')'
,
this
);

//取出单元格的当前内容
var

currentContent=$td.html();
//第一次时走此分支
if

($table.data(
'col-content'
)==
''
){

$table.data(
'col-content'
,currentContent);
$table.data(
'col-td'
,$td);
}
else
{

//上一行与当前行内容相同
if

($table.data(
'col-content'
)==currentContent){
//上一行与当前行内容相同则col-rowspan累加,保存新值
var

rowspan=$table.data(
'col-rowspan'
)+1;
$table.data(
'col-rowspan'
,rowspan);
//值得注意的是如果用了$td.remove()就会对其他列的处理造成影响
$td.hide();
//最后一行的情况比较特殊一点
//比如最后2行td中的内容是一样的,那么到最后一行就应该把此时的col-td里保存的td设置rowspan
if

(++index==$table.data(
'trNum'
))
$table.data(
'col-td'
).attr(
'rowspan'
,$table.data(
'col-rowspan'
));
}
else
{

//上一行与当前行内容不同
//col-rowspan默认为1,如果统计出的col-rowspan没有变化,不处理
if

($table.data(
'col-rowspan'
)!=1){
$table.data(
'col-td'
).attr(
'rowspan'
,$table.data(
'col-rowspan'
));
}
//保存第一次出现不同内容的td,和其内容,重置col-rowspan
$table.data(
'col-td'
,$td);
$table.data(
'col-content'
,$td.html());
$table.data(
'col-rowspan'
,1);
}
}
});
}
//同样是个private函数清理内存之用
function

dispose($table){
$table.removeData();
}
})(jQuery);
主要的说明在注释里应该都有了,代码的确比较简单,像有些地方还值得改进

处理的table内容是从tbody开始查找的,如果没有tbody,那应该给出个更通用化的方案
for(vari=cols.length-1;cols[i]!=undefined;i--)...如果表格数据量大,处理的列也比较多,这里不进行优化会有造成浏览器线程阻塞的风险,可以考虑用setTimeout

其他什么值得改进的,我想应该会不少的
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: