客户要求实现对表格数据的头几行或者头几列进行冻结,即滚动时保持这几行/列不动,通过网上查找代码,参考已有的代码的思路,实现了可以任意对行、列进行冻结。实现原理:创建多个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 - 要锁定的表格元素或者表格ID140 * width - 表格的滚动区域宽度141 * height - 表格的滚动区域高度142 */143 function adjustTableSize(table, width, height) {144 var tableId;145 if (typeof(table) == 'string')146 tableId = table;147 else148 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" freezeRowN
新闻热点
疑难解答