锁定表头和固定列(Fixed table head and columns)
前段时间需要这个功能,但是找了很多都不能完美的实现,不是只能锁定表头,就是浏览器兼容问题什么的,在此就自己做了一个锁定表头和列的js方法,依赖于JQuery。
如使用jQuery1.9.x及以上版本,需要引用jQuery Migrate Plugin库,在jQuery官网即可下载到!
因为方法很简单,就未封装成插件的形式,仅仅以代码方式发布。这里把自己做的方式写出来,以资纪念。
支持IE6+,FF3.6+,Opera9+,Chrome9+
一、实现方式
这里的准备使用4个table实现,具体如下图:
上图红色部分为要取出来的部分,蓝色部分为拼接后可以看到的部分。最终结果如下图
实现后效果:
姓名 | 班级 | 成绩 | |||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
主科 | 文科 | 理科 | 总分 | ||||||||
语文 | 数学 | 英语 | 政治 | 历史 | 地理 | 物理 | 化学 | 生物 | |||
学生1 | 班级3 | 64 | 104 | 150 | 93 | 32 | 82 | 26 | 44 | 83 | 678 |
学生2 | 班级2 | 120 | 66 | 150 | 85 | 5 | 50 | 72 | 32 | 90 | 670 |
学生3 | 班级2 | 133 | 61 | 49 | 97 | 67 | 13 | 64 | 8 | 60 | 552 |
学生4 | 班级3 | 7 | 136 | 105 | 86 | 56 | 11 | 98 | 29 | 18 | 546 |
学生5 | 班级2 | 129 | 146 | 62 | 64 | 67 | 1 | 70 | 57 | 16 | 612 |
学生6 | 班级2 | 45 | 29 | 51 | 91 | 9 | 2 | 37 | 3 | 26 | 293 |
学生7 | 班级1 | 28 | 25 | 127 | 96 | 43 | 90 | 75 | 13 | 28 | 525 |
学生8 | 班级3 | 78 | 64 | 20 | 29 | 70 | 92 | 100 | 69 | 30 | 552 |
学生9 | 班级2 | 65 | 10 | 139 | 19 | 57 | 86 | 57 | 79 | 76 | 588 |
学生10 | 班级2 | 113 | 142 | 4 | 100 | 41 | 69 | 12 | 45 | 20 | 546 |
学生11 | 班级3 | 41 | 84 | 42 | 23 | 89 | 88 | 6 | 4 | 21 | 398 |
学生12 | 班级1 | 4 | 102 | 111 | 61 | 76 | 12 | 25 | 66 | 39 | 496 |
学生13 | 班级2 | 49 | 144 | 56 | 75 | 18 | 58 | 39 | 13 | 88 | 540 |
学生14 | 班级1 | 119 | 81 | 73 | 53 | 37 | 88 | 79 | 69 | 30 | 629 |
学生15 | 班级3 | 120 | 78 | 86 | 58 | 50 | 7 | 20 | 42 | 24 | 485 |
学生16 | 班级1 | 65 | 71 | 9 | 64 | 45 | 31 | 18 | 53 | 5 | 361 |
学生17 | 班级1 | 72 | 139 | 24 | 20 | 39 | 49 | 19 | 21 | 23 | 406 |
学生18 | 班级3 | 50 | 84 | 53 | 70 | 77 | 81 | 38 | 80 | 25 | 558 |
学生19 | 班级1 | 56 | 147 | 134 | 59 | 57 | 31 | 48 | 86 | 7 | 625 |
学生20 | 班级1 | 103 | 38 | 96 | 100 | 21 | 88 | 36 | 37 | 18 | 537 |
学生21 | 班级1 | 133 | 150 | 28 | 37 | 96 | 88 | 12 | 36 | 87 | 667 |
学生22 | 班级2 | 140 | 59 | 42 | 95 | 94 | 50 | 3 | 58 | 63 | 604 |
学生23 | 班级1 | 2 | 51 | 19 | 17 | 19 | 7 | 93 | 35 | 49 | 292 |
学生24 | 班级3 | 67 | 2 | 91 | 23 | 22 | 37 | 79 | 52 | 63 | 436 |
学生25 | 班级3 | 29 | 17 | 149 | 44 | 13 | 29 | 98 | 70 | 6 | 455 |
学生26 | 班级3 | 126 | 117 | 112 | 11 | 100 | 55 | 87 | 1 | 18 | 627 |
学生27 | 班级3 | 144 | 115 | 131 | 97 | 19 | 92 | 79 | 4 | 72 | 753 |
学生28 | 班级2 | 107 | 77 | 143 | 94 | 89 | 90 | 35 | 70 | 3 | 708 |
学生29 | 班级3 | 14 | 33 | 44 | 78 | 5 | 67 | 27 | 49 | 23 | 340 |
学生30 | 班级3 | 77 | 117 | 51 | 75 | 74 | 43 | 25 | 2 | 24 | 488 |
学生31 | 班级1 | 76 | 140 | 148 | 50 | 100 | 33 | 83 | 81 | 23 | 734 |
学生32 | 班级1 | 29 | 25 | 146 | 28 | 79 | 73 | 47 | 8 | 91 | 526 |
学生33 | 班级2 | 96 | 44 | 121 | 3 | 4 | 94 | 17 | 20 | 19 | 418 |
学生34 | 班级2 | 97 | 48 | 68 | 82 | 39 | 16 | 24 | 79 | 79 | 532 |
学生35 | 班级3 | 126 | 69 | 40 | 13 | 48 | 34 | 81 | 5 | 97 | 513 |
学生36 | 班级1 | 144 | 24 | 18 | 71 | 58 | 21 | 12 | 95 | 45 | 488 |
学生37 | 班级1 | 23 | 94 | 93 | 78 | 46 | 88 | 72 | 15 | 90 | 599 |
学生38 | 班级2 | 73 | 103 | 45 | 17 | 69 | 18 | 3 | 67 | 55 | 450 |
学生39 | 班级3 | 19 | 16 | 36 | 18 | 50 | 48 | 19 | 75 | 24 | 305 |
学生40 | 班级1 | 6 | 44 | 50 | 73 | 58 | 21 | 84 | 49 | 68 | 453 |
学生41 | 班级2 | 94 | 98 | 24 | 34 | 52 | 27 | 87 | 95 | 1 | 512 |
学生42 | 班级2 | 27 | 68 | 60 | 75 | 93 | 4 | 38 | 44 | 27 | 436 |
学生43 | 班级3 | 102 | 146 | 138 | 72 | 58 | 19 | 34 | 57 | 60 | 686 |
学生44 | 班级2 | 51 | 81 | 150 | 95 | 8 | 48 | 96 | 90 | 66 | 685 |
学生45 | 班级1 | 93 | 37 | 109 | 84 | 100 | 59 | 90 | 59 | 81 | 712 |
学生46 | 班级2 | 125 | 60 | 32 | 70 | 93 | 65 | 74 | 44 | 77 | 640 |
学生47 | 班级1 | 139 | 45 | 52 | 54 | 6 | 64 | 46 | 45 | 66 | 517 |
学生48 | 班级2 | 14 | 73 | 118 | 4 | 36 | 43 | 24 | 8 | 73 | 393 |
学生49 | 班级3 | 45 | 114 | 114 | 6 | 65 | 94 | 32 | 30 | 1 | 501 |
学生50 | 班级2 | 112 | 77 | 19 | 33 | 30 | 32 | 90 | 18 | 77 | 488 |
学生51 | 班级2 | 19 | 66 | 140 | 36 | 44 | 34 | 62 | 17 | 34 | 452 |
学生52 | 班级2 | 61 | 98 | 107 | 78 | 2 | 17 | 54 | 28 | 89 | 534 |
学生53 | 班级1 | 48 | 23 | 65 | 23 | 70 | 58 | 36 | 45 | 75 | 443 |
学生54 | 班级1 | 81 | 9 | 46 | 37 | 86 | 87 | 83 | 39 | 63 | 531 |
学生55 | 班级1 | 48 | 23 | 145 | 53 | 2 | 9 | 80 | 35 | 31 | 426 |
学生56 | 班级1 | 117 | 92 | 44 | 65 | 3 | 98 | 0 | 70 | 67 | 556 |
学生57 | 班级3 | 148 | 25 | 63 | 29 | 96 | 34 | 34 | 34 | 92 | 555 |
学生58 | 班级1 | 51 | 22 | 97 | 58 | 80 | 16 | 19 | 91 | 20 | 454 |
学生59 | 班级2 | 118 | 1 | 20 | 62 | 26 | 93 | 77 | 66 | 34 | 497 |
学生60 | 班级3 | 129 | 19 | 109 | 78 | 33 | 15 | 74 | 67 | 58 | 582 |
学生61 | 班级3 | 112 | 68 | 65 | 15 | 79 | 63 | 97 | 72 | 85 | 656 |
学生62 | 班级3 | 117 | 14 | 73 | 6 | 6 | 98 | 3 | 81 | 2 | 400 |
学生63 | 班级1 | 87 | 103 | 0 | 2 | 30 | 21 | 43 | 87 | 25 | 398 |
学生64 | 班级2 | 65 | 79 | 49 | 53 | 86 | 33 | 57 | 99 | 83 | 604 |
学生65 | 班级2 | 144 | 7 | 122 | 47 | 11 | 76 | 64 | 66 | 71 | 608 |
学生66 | 班级2 | 18 | 140 | 96 | 54 | 10 | 6 | 45 | 41 | 85 | 495 |
学生67 | 班级2 | 30 | 14 | 70 | 20 | 44 | 25 | 77 | 97 | 20 | 397 |
学生68 | 班级3 | 60 | 7 | 147 | 38 | 7 | 53 | 88 | 54 | 92 | 546 |
学生69 | 班级2 | 86 | 115 | 23 | 90 | 52 | 50 | 89 | 79 | 42 | 626 |
学生70 | 班级3 | 132 | 25 | 21 | 25 | 44 | 86 | 58 | 61 | 3 | 455 |
学生71 | 班级3 | 149 | 102 | 68 | 98 | 96 | 7 | 95 | 25 | 47 | 687 |
学生72 | 班级2 | 28 | 138 | 74 | 30 | 0 | 43 | 95 | 57 | 68 | 533 |
学生73 | 班级3 | 54 | 148 | 81 | 40 | 86 | 23 | 91 | 73 | 95 | 691 |
学生74 | 班级1 | 143 | 39 | 76 | 5 | 55 | 90 | 31 | 18 | 95 | 552 |
学生75 | 班级2 | 83 | 95 | 48 | 86 | 61 | 97 | 68 | 84 | 24 | 646 |
学生76 | 班级1 | 138 | 1 | 141 | 9 | 50 | 1 | 14 | 5 | 11 | 370 |
学生77 | 班级3 | 25 | 33 | 46 | 25 | 62 | 93 | 41 | 43 | 75 | 443 |
学生78 | 班级1 | 18 | 114 | 93 | 22 | 38 | 73 | 66 | 69 | 79 | 572 |
学生79 | 班级3 | 84 | 10 | 72 | 94 | 30 | 95 | 32 | 41 | 56 | 514 |
学生80 | 班级2 | 113 | 39 | 10 | 23 | 28 | 33 | 32 | 7 | 23 | 308 |
学生81 | 班级3 | 83 | 36 | 13 | 13 | 89 | 15 | 39 | 71 | 72 | 431 |
学生82 | 班级3 | 52 | 68 | 39 | 22 | 16 | 9 | 75 | 37 | 95 | 413 |
学生83 | 班级3 | 90 | 0 | 132 | 20 | 36 | 86 | 69 | 39 | 95 | 567 |
学生84 | 班级1 | 61 | 89 | 67 | 10 | 33 | 31 | 99 | 34 | 4 | 428 |
学生85 | 班级1 | 83 | 93 | 105 | 79 | 19 | 30 | 0 | 84 | 7 | 500 |
学生86 | 班级1 | 88 | 143 | 19 | 56 | 9 | 56 | 36 | 89 | 77 | 573 |
学生87 | 班级1 | 70 | 0 | 115 | 66 | 36 | 76 | 0 | 16 | 89 | 468 |
学生88 | 班级3 | 17 | 60 | 49 | 80 | 12 | 99 | 30 | 8 | 1 | 356 |
学生89 | 班级1 | 129 | 128 | 48 | 76 | 47 | 46 | 46 | 89 | 1 | 610 |
学生90 | 班级3 | 143 | 14 | 86 | 1 | 69 | 55 | 85 | 3 | 43 | 499 |
学生91 | 班级2 | 44 | 127 | 143 | 22 | 7 | 18 | 62 | 33 | 44 | 500 |
学生92 | 班级1 | 37 | 41 | 130 | 71 | 17 | 61 | 68 | 1 | 19 | 445 |
学生93 | 班级3 | 45 | 17 | 22 | 10 | 90 | 1 | 83 | 31 | 11 | 310 |
学生94 | 班级2 | 19 | 40 | 99 | 59 | 77 | 1 | 90 | 9 | 68 | 462 |
学生95 | 班级1 | 126 | 19 | 68 | 91 | 53 | 68 | 23 | 87 | 85 | 620 |
学生96 | 班级1 | 131 | 126 | 126 | 53 | 13 | 18 | 70 | 85 | 33 | 655 |
学生97 | 班级1 | 53 | 47 | 33 | 87 | 98 | 98 | 62 | 28 | 95 | 601 |
学生98 | 班级1 | 107 | 88 | 49 | 91 | 6 | 17 | 66 | 24 | 58 | 506 |
学生99 | 班级1 | 118 | 145 | 69 | 4 | 70 | 29 | 43 | 13 | 45 | 536 |
学生100 | 班级2 | 48 | 8 | 115 | 63 | 93 | 53 | 91 | 59 | 93 | 623 |
二、整体的框架
1、最下面的是原始的Table。
2、用左边的table覆盖在上层,命名为tableColumn。
3、用上部的table覆盖在更上层,命名为tableHead。
4、在左上角覆盖固定不动的table,命名为tableFix。
自然在各自的外层都要用div框起来,以便后面的浮动和覆盖等等,所以结构的html如下:
<div id="MyTable_tableLayout"> <div id="MyTable_tableFix"> <table id="MyTable_tableFixClone" border="1" cellspacing="0" cellpadding="0"></table> </div> <div id="MyTable_tableHead"> <table id="MyTable_tableHeadClone" border="1" cellspacing="0" cellpadding="0"></table> </div> <div id="MyTable_tableColumn"> <table id="MyTable_tableColumnClone" border="1" cellspacing="0" cellpadding="0"></table> </div> <div id="MyTable_tableData"> <table id="MyTable" border="1" cellspacing="0" cellpadding="0"></table> </div> </div>
三、代码实现
整体框架结构出来后,下面要做的就是确定每个区域的高度,宽度,定位就算完成了。
首先确定下调用接口,调用时已经有table了,我们希望很简单的一行js即可高定,就用了一个方法实现。由于使用项目中table线宽全部都是1,所以未考虑其他线宽问题。
function FixTable(TableID, FixColumnNumber, width, height)
第一个参数:table的ID,第二个参数:要锁定的列数目,第三个参数:显示的宽度,第四个参数:显示的高度。
(一)首先创建上面所诉的框架出来:
if ($("#" + TableID + "_tableLayout").length != 0) { $("#" + TableID + "_tableLayout").before($("#" + TableID)); $("#" + TableID + "_tableLayout").empty(); } else { $("#" + TableID).after("<div id='" + TableID + "_tableLayout' style='overflow:hidden;height:" + height + "px; width:" + width + "px;'></div>"); } $('<div id="' + TableID + '_tableFix"></div>' + '<div id="' + TableID + '_tableHead"></div>' + '<div id="' + TableID + '_tableColumn"></div>' + '<div id="' + TableID + '_tableData"></div>').appendTo("#" + TableID + "_tableLayout"); var oldtable = $("#" + TableID); var tableFixClone = oldtable.clone(true); tableFixClone.attr("id", TableID + "_tableFixClone"); $("#" + TableID + "_tableFix").append(tableFixClone); var tableHeadClone = oldtable.clone(true); tableHeadClone.attr("id", TableID + "_tableHeadClone"); $("#" + TableID + "_tableHead").append(tableHeadClone); var tableColumnClone = oldtable.clone(true); tableColumnClone.attr("id", TableID + "_tableColumnClone"); $("#" + TableID + "_tableColumn").append(tableColumnClone); $("#" + TableID + "_tableData").append(oldtable); $("#" + TableID + "_tableLayout table").each(function () { $(this).css("margin", "0"); });
(二)计算tableFix,tableHead的高度:
var HeadHeight = $("#" + TableID + "_tableHead thead").height(); HeadHeight += 2; $("#" + TableID + "_tableHead").css("height", HeadHeight); $("#" + TableID + "_tableFix").css("height", HeadHeight);
(三)计算tableFix,tableColumn的宽度:
var ColumnsWidth = 0; var ColumnsNumber = 0; $("#" + TableID + "_tableColumn tr:last td:lt(" + FixColumnNumber + ")").each(function () { ColumnsWidth += $(this).outerWidth(true); ColumnsNumber++; }); ColumnsWidth += 2; if ($.browser.msie) { switch ($.browser.version) { case "7.0": if (ColumnsNumber >= 3) ColumnsWidth--; break; case "8.0": if (ColumnsNumber >= 2) ColumnsWidth--; break; } } $("#" + TableID + "_tableColumn").css("width", ColumnsWidth); $("#" + TableID + "_tableFix").css("width", ColumnsWidth);
(四)为tableHead和tableColumn添加联动的滚动条事件:
$("#" + TableID + "_tableData").scroll(function () { $("#" + TableID + "_tableHead").scrollLeft($("#" + TableID + "_tableData").scrollLeft()); $("#" + TableID + "_tableColumn").scrollTop($("#" + TableID + "_tableData").scrollTop()); });
(五)为较小的table修正样式:
if ($("#" + TableID + "_tableHead").width() > $("#" + TableID + "_tableHead table").width()) { $("#" + TableID + "_tableHead").css("width", $("#" + TableID + "_tableHead table").width()); $("#" + TableID + "_tableData").css("width", $("#" + TableID + "_tableHead table").width() + 17); } if ($("#" + TableID + "_tableColumn").height() > $("#" + TableID + "_tableColumn table").height()) { $("#" + TableID + "_tableColumn").css("height", $("#" + TableID + "_tableColumn table").height()); $("#" + TableID + "_tableData").css("height", $("#" + TableID + "_tableColumn table").height() + 17); }
(六)为整体添加样式,定位:
$("#" + TableID + "_tableFix").css({ "overflow": "hidden", "position": "relative", "z-index": "50", "background-color": "Silver" }); $("#" + TableID + "_tableHead").css({ "overflow": "hidden", "width": width - 17, "position": "relative", "z-index": "45", "background-color": "Silver" }); $("#" + TableID + "_tableColumn").css({ "overflow": "hidden", "height": height - 17, "position": "relative", "z-index": "40", "background-color": "Silver" }); $("#" + TableID + "_tableData").css({ "overflow": "scroll", "width": width, "height": height, "position": "relative", "z-index": "35" }); $("#" + TableID + "_tableFix").offset($("#" + TableID + "_tableLayout").offset()); $("#" + TableID + "_tableHead").offset($("#" + TableID + "_tableLayout").offset()); $("#" + TableID + "_tableColumn").offset($("#" + TableID + "_tableLayout").offset()); $("#" + TableID + "_tableData").offset($("#" + TableID + "_tableLayout").offset());
四、代码如下
完整代码如下:
function FixTable(TableID, FixColumnNumber, width, height) { /// <summary> /// 锁定表头和列 /// <para> sorex.cnblogs.com </para> /// </summary> /// <param name="TableID" type="String"> /// 要锁定的Table的ID /// </param> /// <param name="FixColumnNumber" type="Number"> /// 要锁定列的个数 /// </param> /// <param name="width" type="Number"> /// 显示的宽度 /// </param> /// <param name="height" type="Number"> /// 显示的高度 /// </param> if ($("#" + TableID + "_tableLayout").length != 0) { $("#" + TableID + "_tableLayout").before($("#" + TableID)); $("#" + TableID + "_tableLayout").empty(); } else { $("#" + TableID).after("<div id='" + TableID + "_tableLayout' style='overflow:hidden;height:" + height + "px; width:" + width + "px;'></div>"); } $('<div id="' + TableID + '_tableFix"></div>' + '<div id="' + TableID + '_tableHead"></div>' + '<div id="' + TableID + '_tableColumn"></div>' + '<div id="' + TableID + '_tableData"></div>').appendTo("#" + TableID + "_tableLayout"); var oldtable = $("#" + TableID); var tableFixClone = oldtable.clone(true); tableFixClone.attr("id", TableID + "_tableFixClone"); $("#" + TableID + "_tableFix").append(tableFixClone); var tableHeadClone = oldtable.clone(true); tableHeadClone.attr("id", TableID + "_tableHeadClone"); $("#" + TableID + "_tableHead").append(tableHeadClone); var tableColumnClone = oldtable.clone(true); tableColumnClone.attr("id", TableID + "_tableColumnClone"); $("#" + TableID + "_tableColumn").append(tableColumnClone); $("#" + TableID + "_tableData").append(oldtable); $("#" + TableID + "_tableLayout table").each(function () { $(this).css("margin", "0"); }); var HeadHeight = $("#" + TableID + "_tableHead thead").height(); HeadHeight += 2; $("#" + TableID + "_tableHead").css("height", HeadHeight); $("#" + TableID + "_tableFix").css("height", HeadHeight); var ColumnsWidth = 0; var ColumnsNumber = 0; $("#" + TableID + "_tableColumn tr:last td:lt(" + FixColumnNumber + ")").each(function () { ColumnsWidth += $(this).outerWidth(true); ColumnsNumber++; }); ColumnsWidth += 2; if ($.browser.msie) { switch ($.browser.version) { case "7.0": if (ColumnsNumber >= 3) ColumnsWidth--; break; case "8.0": if (ColumnsNumber >= 2) ColumnsWidth--; break; } } $("#" + TableID + "_tableColumn").css("width", ColumnsWidth); $("#" + TableID + "_tableFix").css("width", ColumnsWidth); $("#" + TableID + "_tableData").scroll(function () { $("#" + TableID + "_tableHead").scrollLeft($("#" + TableID + "_tableData").scrollLeft()); $("#" + TableID + "_tableColumn").scrollTop($("#" + TableID + "_tableData").scrollTop()); }); $("#" + TableID + "_tableFix").css({ "overflow": "hidden", "position": "relative", "z-index": "50", "background-color": "Silver" }); $("#" + TableID + "_tableHead").css({ "overflow": "hidden", "width": width - 17, "position": "relative", "z-index": "45", "background-color": "Silver" }); $("#" + TableID + "_tableColumn").css({ "overflow": "hidden", "height": height - 17, "position": "relative", "z-index": "40", "background-color": "Silver" }); $("#" + TableID + "_tableData").css({ "overflow": "scroll", "width": width, "height": height, "position": "relative", "z-index": "35" }); if ($("#" + TableID + "_tableHead").width() > $("#" + TableID + "_tableFix table").width()) { $("#" + TableID + "_tableHead").css("width", $("#" + TableID + "_tableFix table").width()); $("#" + TableID + "_tableData").css("width", $("#" + TableID + "_tableFix table").width() + 17); } if ($("#" + TableID + "_tableColumn").height() > $("#" + TableID + "_tableColumn table").height()) { $("#" + TableID + "_tableColumn").css("height", $("#" + TableID + "_tableColumn table").height()); $("#" + TableID + "_tableData").css("height", $("#" + TableID + "_tableColumn table").height() + 17); } $("#" + TableID + "_tableFix").offset($("#" + TableID + "_tableLayout").offset()); $("#" + TableID + "_tableHead").offset($("#" + TableID + "_tableLayout").offset()); $("#" + TableID + "_tableColumn").offset($("#" + TableID + "_tableLayout").offset()); $("#" + TableID + "_tableData").offset($("#" + TableID + "_tableLayout").offset()); }
ps:之前的代码有点bug,在高度不够的时候定位会产生错误,在此修正了。
ps2:代码中使用了jquery的msie方法,此方法在1.9.x中删除,需要添加jQuery Migrate Plugin引用,在jQuery官网即可下载到。
ps3:代码在本页中就有,请需要代码的自行右键查看源代码查看即可。
ps4:效果也在本页有示例。
ps5:请阅读完毕后,还有问题,请发消息。
ps6:本人现在上此博客偏少,回复时间过长请见谅。