tablesMergeCell.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. ;(function($) {
  2. $.fn.tablesMergeCell = function(options) {
  3. var defaultsettings= {
  4. automatic:true,
  5. cols: null, // 用数组表示列的索引,从0开始,然后根据指定列来处理(合并)相同内容单元格
  6. rows: null
  7. };
  8. var opts = $.extend(defaultsettings, options);
  9. return this.each(function() {
  10. var cols = opts.cols,
  11. rows = opts.rows;
  12. if(rows==null){
  13. for ( var i = cols.length - 1; cols[i] != undefined; i--) {
  14. tablesMergeCell($(this), cols[i]);
  15. }
  16. }else{
  17. for ( var i = cols.length - 1,k=opts.rows.length-1; cols[i] != undefined; i--,k--) {
  18. tablesMergeCell($(this), cols[i],k);
  19. }
  20. }
  21. dispose($(this));
  22. });
  23. // 如果对javascript的closure和scope概念比较清楚, 这是个插件内部使用的private方法
  24. function tablesMergeCell($table, colIndex,rowIndex) {
  25. $table.data('col-content', ''); // 存放单元格内容
  26. $table.data('col-rowspan', 1); // 存放计算的rowspan值 默认为1
  27. $table.data('col-td', $()); // 存放发现的第一个与前一行比较结果不同td(jQuery封装过的), 默认一个"空"的jquery对象
  28. $table.data('trNum', $('tbody tr', $table).length); // 要处理表格的总行数, 用于最后一行做特殊处理时进行判断之用
  29. // 我们对每一行数据进行"扫面"处理 关键是定位col-td, 和其对应的rowspan
  30. $('tbody tr', $table).each(function(index) {
  31. var $tr = $(this);
  32. // td:eq中的colIndex即列索引
  33. var $td = $('td:eq(' + colIndex + ')', $tr);
  34. var currentContent = $td.html();
  35. if(opts.automatic){ // 内容
  36. // 第一次时走此分支
  37. if ($table.data('col-content') == '') {
  38. $table.data('col-content', currentContent);
  39. $table.data('col-td', $td);
  40. } else {
  41. // 上一行与当前行内容相同
  42. if ($table.data('col-content') == currentContent) {
  43. addRowspan(); // 上一行与当前行内容相同则col-rowspan累加, 保存新值
  44. }else{
  45. newRowspan(); // 上一行与当前行内容不同
  46. }
  47. }
  48. }else{ // 指定
  49. if(opts.rows.length>0){
  50. if(opts.rows[0].length==undefined){
  51. for(var i=0; i<opts.rows.length; i++){
  52. customRowspan(opts.rows[i],opts.rows.length);
  53. }
  54. }else{
  55. for(var i=0; i<opts.rows[rowIndex].length; i++){
  56. customRowspan(opts.rows[rowIndex][i],opts.rows[rowIndex].length);
  57. }
  58. }
  59. }
  60. }
  61. function customRowspan(val,len){
  62. if(index==val){
  63. if ($table.data('col-content') == '') {
  64. if(currentContent==''){
  65. currentContent = true;
  66. }
  67. $table.data('col-content', currentContent);
  68. $td.attr('rowspan', len);
  69. }else{
  70. $td.hide();
  71. }
  72. }
  73. }
  74. function addRowspan(){
  75. var rowspan = $table.data('col-rowspan') + 1;
  76. $table.data('col-rowspan', rowspan);
  77. // 值得注意的是 如果用了$td.remove()就会对其他列的处理造成影响
  78. $td.hide();
  79. // 最后一行的情况比较特殊一点
  80. // 比如最后2行 td中的内容是一样的, 那么到最后一行就应该把此时的col-td里保存的td设置rowspan
  81. if (++index == $table.data('trNum')) {
  82. $table.data('col-td').attr('rowspan', $table.data('col-rowspan'));
  83. }
  84. }
  85. function newRowspan(){
  86. // col-rowspan默认为1, 如果统计出的col-rowspan没有变化, 不处理
  87. if ($table.data('col-rowspan') != 1) {
  88. $table.data('col-td').attr('rowspan', $table.data('col-rowspan'));
  89. }
  90. // 保存第一次出现不同内容的td, 和其内容, 重置col-rowspan
  91. $table.data('col-td', $td);
  92. $table.data('col-content', $td.html());
  93. $table.data('col-rowspan', 1);
  94. }
  95. });
  96. }
  97. // 同样是个private函数 清理内存之用
  98. function dispose($table) {
  99. $table.removeData();
  100. }
  101. };
  102. })(jQuery);