在開發XX車站信息系統時,需要將大量數據顯示在一個巨大的表格內部,由於表格是一個整體,無法分頁,加之數據很多,超出一屏,為了方便用戶,決定使用固定表頭的插件,經過測試,發現JQuery 插件:fixedtableheader可以簡單方便的實現功能。
它的使用很簡單,需要設置的參數也只需2個,很實用。
使用方法:
//引入文件
<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,我很好奇它是怎么實現的,於是就有了下文。
大致原理是:創建一個絕對定位的table,只包含表頭。當表格被用戶拖動超出屏幕時,表頭表格顯示;表格正常顯示時,表頭表格隱藏。
/* 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的.width() 和 CSS width 貌似不統一,有很大區別!所以又細細深入研究了一番,收獲詳見這里。
IE6不能使用position:fixed,具體見這里。
后記:2014-06-17
其實這個根本就達不到所謂的“fixtableheader”的效果,因為它只是簡單的額把所有的表頭都固定在了瀏覽器客戶區的頂部,而非是table所在區域的頂部。
