表頭固定應該是一個用得比較多的功能,參考了網上幾個例子,在幾個常用瀏覽器下顯示不是很完美。而且很多都是基於固定的表格,在編碼時多寫一個固定的表頭,對於動態生成的不知道多少列的表格就無從下手。而且例子中大多只能滿足限定高度的情況,如果限定寬度,出現橫向滾動條就無能為力了。
我的目的就是要像jquery-ui那樣,找到頁面上存在的表格,調用一個方法就可以實現固定表頭的功能。趁着動手學習寫jquery插件的機會,自己寫了一個表頭固定的插件。
使用方式和jquery-ui中的插件一樣,只需要一行代碼 $('#table1').fixHeader({height:100});
下列瀏覽器測試通過
IE7 IE8 IE9 firefox16.0 chrome22.0
說明:
1 需要jquery,開發測試用的jquery-1.8.2,其他版本應該不大
2 表頭部分的<tr>需要寫在<thead>里
3 不限定寬度情況下,自動適應表格寬度(假設滾動條寬度為20px,實際寬度為表格寬度+20px)
4 支持多行表頭固定
5 通常表格所有列都顯示,無橫向滾動條,只需要豎向滾動條的功能。該插件支持限定寬度條件下的表頭固定。
6 限定寬度和高度的條件下固定表頭顯示時,表頭固定功能無法單純通過css來實現,需要通過js實現,會有輕微閃爍
7 已經考慮table和th,td的border-width設置成不同值的情況
8 已經考慮了表頭中綁定的事件,原表頭中綁定的事件仍然保留
使用方法:
限定高度:$('#table1').fixHeader({height:100});
限定高度和寬度:$('#table3').fixHeader({height:100,width:500});
下面為完整代碼

/*! * fixHeader 1.0.1 * Copyright 2012 chokobo * * make table header fixed * * notice: set th,id border-width in IE * * tested browser: IE7 IE8 IE9 firefox16.0 chrome22.0 */ (function( $, undefined ) { $.fn.fixHeader = function(options){ var defaults = { width: '', height: '' }; options = $.extend({}, defaults, options); var elem = this; if(options.height == ''){ return this; } var thead = elem.find('thead'); var fixTable = elem.clone().empty().removeAttr('id'); //set head default background-color if(fixTable.css('background-color') == 'transparent' || fixTable.css('background-color') == ''){ fixTable.css('background-color', '#fff'); } fixTable.css({ 'position': 'absolute', 'top': '0px', 'border-bottom': $('tr:eq(0)', thead).find('th:eq(0), td:eq(0)').css('border-bottom-width') }); $('tr:eq(0)', thead).find('th, td').each(function(){ var col = $(this); if($.browser.mozilla){ col.width(col.width()); } else if($.browser.chrome){ var colBorderWidth = parseInt(col.css('border-right-width')); if(colBorderWidth){ col.width(col.width()+colBorderWidth); } else{ col.width(col.width()); } } else if($.browser.msie){ var colBorderWidth = parseInt(col.css('border-right-width')); if(colBorderWidth){ col.width(col.width()+colBorderWidth+colBorderWidth/2); } else{ col.width(col.width()); } } else{ var colBorderWidth = parseInt(col.css('border-right-width')); if(colBorderWidth){ col.width(col.width()+colBorderWidth); } else{ col.width(col.width()); } } }); //make head var dummyHead = thead.clone(); thead.appendTo(fixTable); dummyHead.prependTo(elem); var tbodyWrapper = elem.wrap('<div class="body-wrapper"></div>').parent(); var tableWrapper = tbodyWrapper.wrap('<div class="table-wrapper" style="position:relative;"/>').parent(); setTableWidth(); setWrapperSize(); fixTable.prependTo(tableWrapper); return this; function setTableWidth(){ if($.browser.mozilla){ elem.width(elem.width()); fixTable.css('width',elem.css('width')); } else if($.browser.chrome){ elem.width(elem.outerWidth()); fixTable.width(elem.outerWidth()); } else if($.browser.msie){ elem.width(elem.outerWidth()); fixTable.width(elem.outerWidth()); } else{ elem.width(elem.outerWidth()); fixTable.width(elem.outerWidth()); } } function setWrapperSize(){ var elemWidth = elem.outerWidth(true); var elemHeight = elem.outerHeight(true); var scrollBarWidth = 20; if(options.width == ''){ tbodyWrapper.css({ 'width': (elemWidth+scrollBarWidth) + 'px', 'height': options.height, 'overflow-x': 'hidden', 'overflow-y': 'auto' }); } else{ if(elemWidth <= options.width){ tbodyWrapper.css({ 'width': options.width+'px', 'height': options.height, 'overflow-x': 'hidden', 'overflow-y': 'auto' }); } else{ tableWrapper.css({ 'width': options.width, 'height': options.height, 'overflow': 'auto' }); tableWrapper.scroll(function(){ fixTable.css('top',tableWrapper.scrollTop()+'px'); }); } } } }; })( jQuery );