客户要求实现对表格数据的头几行或者头几列进行冻结,即滚动时保持这几行/列不动,通过网上查找代码,参考已有的代码的思路,实现了可以任意对行、列进行冻结。 
实现原理: 
创建多个div,div之间通过css实现层叠,每个div放置当前表格的克隆。例如:需要行冻结时,创建存放冻结行表格的div,通过设置z-index属性和position属性,让冻结行表格在数据表格的上层。同理,需要列冻结时,创建存放冻结列表格的div,并放置在数据表格的上层。如果需要行列都冻结时,则除了创建冻结行、冻结列表格的div,还需要创建左上角的固定行列表格的div,并放置在所有div的最上层。 
处理表格的滚动事件,在表格横向或者纵向滚动时,同时让相应的冻结行和冻结列也同步滚动。 
处理html的resize事件,同步修改表格的滚动区域宽度和高度 
代码如下:

  1 /*
  2  * 锁定表头和列
  3  * 
  4  * 参数定义
  5  *     table - 要锁定的表格元素或者表格ID
  6  *     freezeRowNum - 要锁定的前几行行数,如果行不锁定,则设置为0
  7  *     freezeColumnNum - 要锁定的前几列列数,如果列不锁定,则设置为0
  8  *     width - 表格的滚动区域宽度
  9  *     height - 表格的滚动区域高度
 10  */
 11 function freezeTable(table, freezeRowNum, freezeColumnNum, width, height) {
 12     if (typeof(freezeRowNum) == 'string')
 13         freezeRowNum = parseInt(freezeRowNum)
 14         
 15     if (typeof(freezeColumnNum) == 'string')
 16         freezeColumnNum = parseInt(freezeColumnNum)
 17 
 18     var tableId;
 19     if (typeof(table) == 'string') {
 20         tableId = table;
 21         table = $('#' + tableId);
 22     } else
 23         tableId = table.attr('id');
 24         
 25     var divTableLayout = $("#" + tableId + "_tableLayout");
 26     
 27     if (divTableLayout.length != 0) {
 28         divTableLayout.before(table);
 29         divTableLayout.empty();
 30     } else {
 31         table.after("<div id='" + tableId + "_tableLayout' style='overflow:hidden;height:" + height + "px; width:" + width + "px;'></div>");
 32         
 33         divTableLayout = $("#" + tableId + "_tableLayout");
 34     }
 35     
 36     var html = '';
 37     if (freezeRowNum > 0 && freezeColumnNum > 0)
 38         html += '<div id="' + tableId + '_tableFix" style="padding: 0px;"></div>';
 39         
 40     if (freezeRowNum > 0)
 41         html += '<div id="' + tableId + '_tableHead" style="padding: 0px;"></div>';
 42         
 43     if (freezeColumnNum > 0)
 44         html += '<div id="' + tableId + '_tableColumn" style="padding: 0px;"></div>';
 45         
 46     html += '<div id="' + tableId + '_tableData" style="padding: 0px;"></div>';
 47     
 48     
 49     $(html).appendTo("#" + tableId + "_tableLayout");
 50     
 51     var divTableFix = freezeRowNum > 0 && freezeColumnNum > 0 ? $("#" + tableId + "_tableFix") : null;
 52     var divTableHead = freezeRowNum > 0 ? $("#" + tableId + "_tableHead") : null;
 53     var divTableColumn = freezeColumnNum > 0 ? $("#" + tableId + "_tableColumn") : null;
 54     var divTableData = $("#" + tableId + "_tableData");
 55     
 56     divTableData.append(table);
 57     
 58     if (divTableFix != null) {
 59         var tableFixClone = table.clone(true);
 60         tableFixClone.attr("id", tableId + "_tableFixClone");
 61         divTableFix.append(tableFixClone);
 62     }
 63     
 64     if (divTableHead != null) {
 65         var tableHeadClone = table.clone(true);
 66         tableHeadClone.attr("id", tableId + "_tableHeadClone");
 67         divTableHead.append(tableHeadClone);
 68     }
 69     
 70     if (divTableColumn != null) {
 71         var tableColumnClone = table.clone(true);
 72         tableColumnClone.attr("id", tableId + "_tableColumnClone");
 73         divTableColumn.append(tableColumnClone);
 74     }
 75     
 76     $("#" + tableId + "_tableLayout table").css("margin", "0");
 77     
 78     if (freezeRowNum > 0) {
 79         var HeadHeight = 0;
 80         var ignoreRowNum = 0;
 81         $("#" + tableId + "_tableHead tr:lt(" + freezeRowNum + ")").each(function () {
 82             if (ignoreRowNum > 0)
 83                 ignoreRowNum--;
 84             else {
 85                 var td = $(this).find('td:first, th:first');
 86                 HeadHeight += td.outerHeight(true);
 87                 
 88                 ignoreRowNum = td.attr('rowSpan');
 89                 if (typeof(ignoreRowNum) == 'undefined')
 90                     ignoreRowNum = 0;
 91                 else
 92                     ignoreRowNum = parseInt(ignoreRowNum) - 1;
 93             }
 94         });
 95         HeadHeight += 2;
 96         
 97         divTableHead.css("height", HeadHeight);
 98         divTableFix != null && divTableFix.css("height", HeadHeight);
 99     }
100     
101     if (freezeColumnNum > 0) {
102         var ColumnsWidth = 0;
103         var ColumnsNumber = 0;
104         $("#" + tableId + "_tableColumn tr:eq(" + freezeRowNum + ")").find("td:lt(" + freezeColumnNum + "), th:lt(" + freezeColumnNum + ")").each(function () {
105             if (ColumnsNumber >= freezeColumnNum)
106                 return;
107                 
108             ColumnsWidth += $(this).outerWidth(true);
109             
110             ColumnsNumber += $(this).attr('colSpan') ? parseInt($(this).attr('colSpan')) : 1;
111         });
112         ColumnsWidth += 2;
113 
114         divTableColumn.css("width", ColumnsWidth);
115         divTableFix != null && divTableFix.css("width", ColumnsWidth);
116     }
117     
118     divTableData.scroll(function () {
119         divTableHead != null && divTableHead.scrollLeft(divTableData.scrollLeft());
120         
121         divTableColumn != null && divTableColumn.scrollTop(divTableData.scrollTop());
122     });
123     
124     divTableFix != null && divTableFix.css({ "overflow": "hidden", "position": "absolute", "z-index": "50" });
125     divTableHead != null && divTableHead.css({ "overflow": "hidden", "width": width - 17, "position": "absolute", "z-index": "45" });
126     divTableColumn != null && divTableColumn.css({ "overflow": "hidden", "height": height - 17, "position": "absolute", "z-index": "40" });
127     divTableData.css({ "overflow": "scroll", "width": width, "height": height, "position": "absolute" });
128     
129     divTableFix != null && divTableFix.offset(divTableLayout.offset());
130     divTableHead != null && divTableHead.offset(divTableLayout.offset());
131     divTableColumn != null && divTableColumn.offset(divTableLayout.offset());
132     divTableData.offset(divTableLayout.offset());
133 }
134 
135 /*
136  * 调整锁定表的宽度和高度,这个函数在resize事件中调用
137  * 
138  * 参数定义
139  *     table - 要锁定的表格元素或者表格ID
140  *     width - 表格的滚动区域宽度
141  *     height - 表格的滚动区域高度
142  */
143 function adjustTableSize(table, width, height) {
144     var tableId;
145     if (typeof(table) == 'string')
146         tableId = table;
147     else
148         tableId = table.attr('id');
149     
150     $("#" + tableId + "_tableLayout").width(width).height(height);
151     $("#" + tableId + "_tableHead").width(width - 17);
152     $("#" + tableId + "_tableColumn").height(height - 17);
153     $("#" + tableId + "_tableData").width(width).height(height);
154 }
155 
156 function pageHeight() {
157     if ($.browser.msie) {
158         return document.compatMode == "CSS1Compat" ? document.documentElement.clientHeight : document.body.clientHeight;
159     } else {
160         return self.innerHeight;
161     }
162 };
163 
164 //返回当前页面宽度
165 function pageWidth() {
166     if ($.browser.msie) {
167         return document.compatMode == "CSS1Compat" ? document.documentElement.clientWidth : document.body.clientWidth;
168     } else {
169         return self.innerWidth;
170     }
171 };
172 
173 $(document).ready(function() {
174     var table = $("table");
175     var tableId = table.attr('id');
176     var freezeRowNum = table.attr('freezeRowNum');
177     var freezeColumnNum = table.attr('freezeColumnNum');
178     
179     if (typeof(freezeRowNum) != 'undefined' || typeof(freezeColumnNum) != 'undefined') {
180         freezeTable(table, freezeRowNum || 0, freezeColumnNum || 0, pageWidth(), pageHeight());
181         
182         var flag = false;
183         $(window).resize(function() {
184             if (flag) 
185                 return ;
186             
187             setTimeout(function() { 
188                 adjustTableSize(tableId, pageWidth(), pageHeight()); 
189                 flag = false; 
190             }, 100);
191             
192             flag = true;
193         });
194     }
195 });

使用时,只要在table元素设置freezeRowNum和freezeColumnNum属性值,即可实现冻结效果

<table id="reportTable" width="1900" freezeRowNum="2" freezeColumnNum="2" class="report" align="center">
...
</table>

 

posted on 2015-04-28 15:47  USID  阅读(1406)  评论(0编辑  收藏  举报