在開發XX車站信息系統時,須要將大量數據顯示在一個巨大的表格內部,因爲表格是一個總體,沒法分頁,加之數據不少,超出一屏,爲了方便用戶,決定使用固定表頭的插件,通過測試,發現JQuery 插件:fixedtableheader能夠簡單方便的實現功能。javascript
它的使用很簡單,須要設置的參數也只需2個,很實用。php
使用方法:css
//引入文件 <script type="mce-text/javascript" src="http://i.cnblogs.com/jquery.min.js"></script> <script type="mce-text/javascript" src="http://i.cnblogs.com/jquery.fixedtableheader.min.js">< //綁定表格,headerrowsize 後面的參數是綁定須要固定的表頭的行數 <script type="mce-text/javascript"> $(document).ready(function() { $('.tbl').fixedtableheader({ highlightrow: true, headerrowsize: 4 }); }); </script>
使用時,我發現js文件只有 4KB,我很好奇它是怎麼實現的,因而就有了下文。html
大體原理是:建立一個絕對定位的table,只包含表頭。當表格被用戶拖動超出屏幕時,表頭表格顯示;表格正常顯示時,表頭表格隱藏。java
/* Copyright (c) 2009 Mustafa OZCAN (http://www.mustafaozcan.net) * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses. * Version: .0.2 * Requires: jquery.1.3+ */ jQuery.fn.fixedtableheader = function(options) { var settings = jQuery.extend({ //jQuery.extend( target [, object1 ] [, objectN ] ) headerrowsize: 1, //這是默認參數 highlightrow: false, highlightclass: "highlight" }, options); //用戶設置的參數 //若是用戶設置參數,會覆蓋對應的默認參數 this.each(function(i) { //處理每一個table(該插件使用class屬性綁定,會存在多個table) var $tbl = $(this); var $tblhfixed = $tbl.find("tr:lt(" + settings.headerrowsize + ")"); //找到要固定表頭tr var headerelement = "th"; if ($tblhfixed.find(headerelement).length == 0) headerelement = "td"; //沒有th,默認td爲表頭單元格 if ($tblhfixed.find(headerelement).length > 0) { //有th單元格 $tblhfixed.find(headerelement).each(function() { $(this).css("width", $(this).width()); //設置表頭th寬度 }); var $clonedTable = $tbl.clone().empty(); //建立表頭表格,即一對完整的table標籤 var tblwidth = GetTblWidth($tbl); $clonedTable.attr("id", "fixedtableheader" + i).css({ //設置懸浮表頭絕對定位的位置 "position": "fixed", "top": "0", "left": $tbl.offset().left //.offset(): 獲取表格的左邊距 }).append($tblhfixed.clone()).width(tblwidth).hide().appendTo($("body")); //將表頭插入table標籤中 if (settings.highlightrow) //鼠標移太高亮 $("tr:gt(" + (settings.headerrowsize - 1) + ")", $tbl).hover(function() { $(this).addClass(settings.highlightclass); }, function() { $(this).removeClass(settings.highlightclass); }); $(window).scroll(function() { //當滾動條發生變化時觸發scroll事件 if (jQuery.browser.msie && jQuery.browser.version == "6.0") //IE6.0 $clonedTable.css({ // "position": "absolute", "top": $(window).scrollTop(), "left": $tbl.offset().left }); else $clonedTable.css({ "position": "fixed", "top": "0", "left": $tbl.offset().left - $(window).scrollLeft() }) var sctop = $(window).scrollTop(); //頁面滾動條向下滾動的高度,也即頁面被隱藏的高度 var elmtop = $tblhfixed.offset().top; //此時原始表格距離瀏覽器客戶區頂端的高度 if (sctop > elmtop && sctop <= (elmtop + $tbl.height() - $tblhfixed.height())) $clonedTable.show(); //原來的表頭被滾動的不可見而且表格主體還沒有被滾動出屏幕 else $clonedTable.hide(); // }); $(window).resize(function() { if ($clonedTable.outerWidth() != $tbl.outerWidth()) { //若懸浮表跟不上resize的變化 $tblhfixed.find(headerelement).each(function(index) { //從新設置懸浮表頭clonedTable每一個th/td的寬度 var w = $(this).width(); $(this).css("width", w); $clonedTable.find(headerelement).eq(index).css("width", w); }); $clonedTable.width($tbl.outerWidth()); //設置懸浮表的寬度,注意這裏.width()和css('width')的區別 } $clonedTable.css("left", $tbl.offset().left); //jquery中offset是相對於瀏覽器客戶區的相對偏移 }); } }); function GetTblWidth($tbl) { //獲取元素寬度(包括padding和border) var tblwidth = $tbl.outerWidth(); return tblwidth; } };
在註釋該代碼過程當中,一個很嚴重的疑惑產生了:jquery
JQuery的.width() 和 CSS width 貌似不統一,有很大區別!因此又細細深刻研究了一番,收穫詳見這裏。瀏覽器
IE6不能使用position:fixed,具體見這裏。app
後記:2014-06-17ide
其實這個根本就達不到所謂的「fixtableheader」的效果,由於它只是簡單的額把全部的表頭都固定在了瀏覽器客戶區的頂部,而非是table所在區域的頂部。測試