表头固定(利用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 相关文章推荐
ajax 文件上传应用简单实现
Mar 03 Javascript
DOM下的节点属性和操作小结
May 14 Javascript
一些mootools的学习资源
Feb 07 Javascript
JavaScript避免代码的重复执行经验技巧分享
Apr 17 Javascript
在JS方法中返回多个值的方法汇总
May 20 Javascript
JS函数arguments数组获得实际传参数个数的实现方法
May 28 Javascript
jQuery仿京东商城楼梯式导航定位菜单
Jul 25 Javascript
微信小程序 下拉列表的实现实例代码
Mar 08 Javascript
three.js加载obj模型的实例代码
Nov 10 Javascript
JavaScript设计模式之工厂模式和抽象工厂模式定义与用法分析
Jul 26 Javascript
Nginx设置为Node.js的前端服务器方法总结
Mar 27 Javascript
layui表格数据复选框回显设置方法
Sep 13 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简介
2006/10/09 PHP
php操作sqlserver关于时间日期读取的小小见解
2009/11/29 PHP
php中http_build_query 的一个问题
2012/03/25 PHP
thinkPHP数据查询常用方法总结【select,find,getField,query】
2017/03/15 PHP
JavaScript 继承详解(四)
2009/07/13 Javascript
在JavaScript中获取请求的URL参数[正则]
2010/12/25 Javascript
使用JavaScript构建JSON格式字符串实现步骤
2013/03/22 Javascript
jQuery回车实现登录简单实现
2013/08/20 Javascript
非常酷炫的Bootstrap图片轮播动画
2016/05/27 Javascript
JS实现n秒后自动跳转的两种方法
2020/11/30 Javascript
jQuery中的insertBefore(),insertAfter(),after(),before()区别介绍
2016/09/01 Javascript
使用JS批量选中功能实现更改数据库中的status状态值(批量展示)
2016/11/22 Javascript
Angular实现的简单定时器功能示例
2017/12/28 Javascript
微信小程序实现之手势锁功能实例代码
2018/07/19 Javascript
webpack打包nodejs项目的方法
2018/09/26 NodeJs
js限制input只能输入有效的数字(第一个不能是小数点)
2018/09/28 Javascript
Vue项目报错:Uncaught SyntaxError: Unexpected token
2018/11/10 Javascript
vue2中引用及使用 better-scroll的方法详解
2018/11/15 Javascript
Vue axios全局拦截 get请求、post请求、配置请求的实例代码
2018/11/28 Javascript
JavaScript格式化json和xml的方法示例
2019/01/22 Javascript
js实现一款简单踩白块小游戏(曾经很火)
2019/12/02 Javascript
JavaScript HTML DOM 元素 (节点)新增,编辑,删除操作实例分析
2020/03/02 Javascript
VSCode 配置uni-app的方法
2020/07/11 Javascript
JavaScript实现弹出窗口效果
2020/12/09 Javascript
[45:59]EG vs OG 2018国际邀请赛小组赛BO2 第二场 8.17
2018/08/18 DOTA
Python实现JSON反序列化类对象的示例
2018/01/31 Python
Python 实现取矩阵的部分列,保存为一个新的矩阵方法
2018/11/14 Python
pytorch 固定部分参数训练的方法
2019/08/17 Python
python实时监控logstash日志代码
2020/04/27 Python
html5页面结构_动力节点Java学院整理
2017/07/10 HTML / CSS
运动鞋中的劳斯莱斯:索康尼(SAUCONY)
2017/08/09 全球购物
欧洲品牌瓷器餐具网上商店:Porzellantreff.de
2018/04/04 全球购物
EJB面试题
2015/07/28 面试题
Python+Appium实现自动抢微信红包
2021/05/21 Python
Python的三个重要函数详解
2022/01/18 Python
win11自动弹出虚拟键盘怎么关闭? Win11关闭虚拟键盘的技巧
2023/01/09 数码科技