表头固定(利用jquery实现原理介绍)


Posted in Javascript onNovember 08, 2012

表头固定应该是一个用得比较多的功能,参考了网上几个例子,在几个常用浏览器下显示不是很完美。而且很多都是基于固定的表格,在编码时多写一个固定的表头,对于动态生成的不知道多少列的表格就无从下手。而且例子中大多只能满足限定高度的情况,如果限定宽度,出现横向滚动条就无能为力了。

我的目的就是要像jquery-ui那样,找到页面上存在的表格,调用一个方法就可以实现固定表头的功能。趁着动手学习写jquery插件的机会,自己写了一个表头固定的插件。
使用方式和jquery-ui中的插件一样,只需要一行代码 $('#table1').fixHeader({height:100});

下列浏览器测试通过
IE7 IE8 firefox16.0 chrome22.0
目前已知IE9下列不能对齐,手头暂时没有IE9来调试,以后再想法解决。

说明:
1 需要jquery,开发测试用的jquery-1.8.2,其他版本应该不大
2 表头部分的<tr>需要写在<thead>里
3 不限定宽度情况下,自动适应表格宽度(假设滚动条宽度为20px,实际宽度为表格宽度+20px)
4 支持多行表头固定
5 通常表格所有列都显示,无横向滚动条,只需要竖向滚动条的功能。该插件支持限定宽度条件下的表头固定。
6 限定宽度和高度的条件下固定表头显示时,表头固定功能无法单纯通过css来实现,需要通过js实现,会有轻微闪烁
7 已经考虑table和th,td的border-width设置成不同值的情况
8 已经考虑了表头中绑定的事件,原表头中绑定的事件仍然保留

特别注意:IE浏览器下,一定要设置表格中td和th的border-width,否则无法正确设置列宽,表头和数据部分会错位
使用方法:
限定高度:$('#table1').fixHeader({height:100});
限定高度和宽度:$('#table3').fixHeader({height:100,width:500});

下面为完整代码

/*! 
* fixHeader 1.0.0 
* Copyright 2012 chokobo 
* 
* make table header fixed 
* 
* notice: set th,id border-width in IE 
* 
* tested browser: IE7 IE8 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-width')); 
col.width(col.width()+colBorderWidth); 
} 
else if($.browser.msie){ 
var colBorderWidth = parseInt(col.css('border-width')); 
if(colBorderWidth){ 
col.width(col.width()+colBorderWidth+colBorderWidth/2);//IE7?? 
} 
} 
}); 
//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 );

/* 
功能:固定表?。 
使用容器的ID?行?定$("#div").chromatable({width: "100%",height: "100%", scrolling: "yes"}) 
table必?包含有<thead>?嘶` 
??担?o。 
*/ 
(function($){ 
$.chromatable = { 
defaults: { 
width: "900px", //?定容器??度,待?U展程式 
height: "300px", //?定容器高度,待?U展程式 
scrolling: "yes" //yes跟?IE?L??l而滑?? no固定在?面上?H容器?L??l滑? 
} 
}; 
$.fn.chromatable = function(options){ 
var options = $.extend({}, $.chromatable.defaults, options); 
return this.each(function(){ 
var $divObj = $(this); 
var $tableObj = $divObj.find("table"); 
var $uniqueID = $tableObj.attr("ID") + ("wrapper"); 
var $class = $tableObj.attr("class"); 
var $tableWidth = $tableObj.width(); 
var top = $("#"+$tableObj.attr("ID")).offset().top; 
var left = $("#"+$tableObj.attr("ID")).offset().left 
$divObj.append("<table class='"+$class+"' id='"+$uniqueID+"' style='position:absolute;top:" +top+"px;left:"+left+"px;' width='"+$tableWidth+"' border='0' cellspacing='0' cellpadding='0'><thead>"+$("#"+$tableObj.attr("ID")).find("thead").html()+"</thead></table>"); $.each($("#"+$tableObj.attr("ID")).find("thead th"), function(i,item){ 
$("#"+$uniqueID).find("thead th").eq(i).width($(item).width()); 
$(item).width($(item).width()); 
}); 
if(options.scrolling === "yes") 
{ 
scrollEvent($tableObj.attr("ID"), $uniqueID); 
} 
resizeEvent($tableObj.attr("ID"), $uniqueID); 
}); 
function scrollEvent(tableId, uniqueID) 
{ 
var element = $("#"+uniqueID); 
$(window).scroll(function(){ 
var top = $("#"+tableId).offset().top; 
var scrolls = $(this).scrollTop(); 
if (scrolls > top) { 
if (window.XMLHttpRequest) { 
element.css({ 
position: "fixed", 
top: 0 
}); 
} else { 
element.css({ 
top: scrolls 
}); 
} 
}else { 
element.css({ 
position: "absolute", 
top: top 
}); 
} 
}); 
}; 
function resizeEvent(tableId, uniqueID) 
{ 
var element = $("#"+uniqueID); 
$(window).resize(function(){ 
var top = $("#"+tableId).offset().top; 
var scrolls = $(this).scrollTop(); 
if (scrolls > top) { 
if (window.XMLHttpRequest) { 
element.css({ 
position: "fixed", 
top: 0 
}); 
} else { 
element.css({ 
top: scrolls 
}); 
} 
}else { 
element.css({ 
position: "absolute", 
top: top 
}); 
} 
}); 
} 
}; 
})(jQuery);
Javascript 相关文章推荐
破除网页鼠标右键被禁用的绝招大全
Dec 27 Javascript
Some tips of wmi scripting in jscript (1)
Apr 03 Javascript
js输出阴历、阳历、年份、月份、周示例代码
Jan 29 Javascript
JS实现控制表格行文本对齐的方法
Mar 30 Javascript
layer实现弹窗提交信息
Dec 12 Javascript
深入理解jquery中extend的实现
Dec 22 Javascript
JS闭包与延迟求值用法示例
Dec 22 Javascript
vue2.0的contextmenu右键弹出菜单的实例代码
Jul 24 Javascript
微信小程序实现的贪吃蛇游戏【附源码下载】
Jan 03 Javascript
解决vue-cli + webpack 新建项目出错的问题
Mar 20 Javascript
echarts统计x轴区间的数值实例代码详解
Jul 07 Javascript
javascript中的with语句学习笔记及用法
Feb 17 Javascript
Javascript继承(上)——对象构建介绍
Nov 08 #Javascript
异步javascript的原理和实现技巧介绍
Nov 08 #Javascript
找出字符串中出现次数最多的字母和出现次数精简版
Nov 07 #Javascript
jquery 如何动态添加、删除class样式方法介绍
Nov 07 #Javascript
探索Emberjs制作一个简单的Todo应用
Nov 07 #Javascript
关于使用 jBox 对话框的提交不能弹出问题解决方法
Nov 07 #Javascript
seajs1.3.0源码解析之module依赖有序加载
Nov 07 #Javascript
You might like
php学习笔记 数组的常用函数
2011/06/13 PHP
PHP UTF8中文字符截断函数代码
2012/09/11 PHP
基于PHP实现通过照片获取ip地址
2016/04/26 PHP
ext读取两种结构的xml的代码
2008/11/05 Javascript
基于jquery的点击链接插入链接内容的代码
2012/07/31 Javascript
jQuery写的日历(包括日历的样式及功能)
2013/04/23 Javascript
JS小功能(操作Table--动态添加删除表格及数据)实现代码
2013/11/28 Javascript
node.js+express制作网页计算器
2016/01/17 Javascript
nodejs实现邮件发送服务实例分享
2017/03/29 NodeJs
js实现会跳动的日历效果(完整实例)
2017/10/18 Javascript
Vue插件打包与发布的方法示例
2018/08/20 Javascript
JavaScript中join()、splice()、slice()和split()函数用法示例
2018/08/24 Javascript
解决angularJS中input标签的ng-change事件无效问题
2018/09/13 Javascript
深入理解Vue.js轻量高效的前端组件化方案
2018/12/10 Javascript
详解node登录接口之密码错误限制次数(含代码)
2019/10/25 Javascript
在vue项目中引用Antv G2,以饼图为例讲解
2020/10/28 Javascript
vue的$http的get请求要加上params操作
2020/11/12 Javascript
vue单元格多列合并的实现
2020/11/26 Vue.js
js调用网络摄像头的方法
2020/12/05 Javascript
浅谈Python 的枚举 Enum
2017/06/12 Python
对TensorFlow的assign赋值用法详解
2018/07/30 Python
python中使用 xlwt 操作excel的常见方法与问题
2019/01/13 Python
python傅里叶变换FFT绘制频谱图
2019/07/19 Python
Tensorflow实现将标签变为one-hot形式
2020/05/22 Python
Python用户自定义异常的实现
2020/12/25 Python
CSS3 实现童年的纸飞机
2019/05/05 HTML / CSS
皮姆斯勒语言学习:Pimsleur Language Programs
2018/06/30 全球购物
N:Philanthropy官网:美国洛杉矶基础款服装
2020/06/09 全球购物
正隆泰信息技术有限公司上机题
2012/06/14 面试题
先进德育工作者事迹材料
2014/01/24 职场文书
森林防火工作方案
2014/02/14 职场文书
优秀党务工作者事迹材料
2014/05/07 职场文书
2014流动人口计划生育工作总结
2014/12/20 职场文书
公证书格式
2015/01/23 职场文书
改进工作作风心得体会
2016/01/23 职场文书
python如何进行基准测试
2021/04/26 Python