表头固定(利用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 相关文章推荐
HTML中事件触发列表与解说
Jul 09 Javascript
jQuery中append()方法用法实例
Jan 08 Javascript
jquery实现漫天雪花飞舞的圣诞祝福雪花效果代码分享
Aug 20 Javascript
微信QQ的二维码登录原理js代码解析
Jun 23 Javascript
jquery html5 视频播放控制代码
Nov 06 Javascript
Bootstrap下拉菜单Dropdowns的实现代码
Mar 17 Javascript
vue实现动态数据绑定
Apr 28 Javascript
Angularjs的键盘事件的绑定
Jul 27 Javascript
Mobile Web开发基础之四--处理手机设备的横竖屏问题
Aug 11 Javascript
javascript Function函数理解与实战
Dec 01 Javascript
vue实现键盘输入支付密码功能
Aug 18 Javascript
微信小程序地图(map)组件点击(tap)获取经纬度的方法
Jan 10 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 字符转义 注意事项
2009/05/27 PHP
PHP使用CURL实现多线程抓取网页
2015/04/30 PHP
详解关于php的xdebug配置(编辑器vscode)
2019/01/29 PHP
Jquery操作Select 简单方便 一个js插件搞定
2009/11/12 Javascript
js中查找最近的共有祖先元素的实现代码
2010/12/30 Javascript
javascript操作字符串的原生方法
2014/12/22 Javascript
ExpressJS入门实例
2015/01/14 Javascript
jquery制作多功能轮播图插件
2015/04/02 Javascript
基于javascript html5实现3D翻书特效
2016/03/14 Javascript
jQuery实现点击水纹波动动画
2016/04/10 Javascript
Bootstrap编写一个同时适用于PC、平板、手机的登陆页面
2016/06/30 Javascript
Angularjs中controller的三种写法分享
2016/09/21 Javascript
基于JavaScript实现前端文件的断点续传
2016/10/17 Javascript
基于JS组件实现拖动滑块验证功能(代码分享)
2016/11/18 Javascript
jQuery实现圣诞节礼物动画案例解析
2016/12/25 Javascript
Vue单页面应用保证F5强刷不清空数据的解决方案
2018/01/31 Javascript
Vue进度条progressbar组件功能
2018/04/17 Javascript
微信小程序实现列表页的点赞和取消点赞功能
2018/11/02 Javascript
vscode中eslint插件的配置(prettier配置无效)
2019/09/10 Javascript
VSCode launch.json配置详细教程
2020/06/18 Javascript
Python Web框架Flask中使用七牛云存储实例
2015/02/08 Python
谈谈Python进行验证码识别的一些想法
2016/01/25 Python
python如何在终端里面显示一张图片
2016/08/17 Python
Python Socket传输文件示例
2017/01/16 Python
Python SQLAlchemy入门教程(基本用法)
2019/11/11 Python
TensorFlow实现保存训练模型为pd文件并恢复
2020/02/06 Python
Pycharm 设置默认解释器路径和编码格式的操作
2021/02/05 Python
JAVA程序员自荐书
2014/01/30 职场文书
安全协议书范本
2014/04/21 职场文书
销售竞赛活动方案
2014/08/23 职场文书
乡镇党委书记个人整改措施
2014/09/15 职场文书
班级光棍节联谊会策划书
2014/10/10 职场文书
2014年世界艾滋病日宣传活动总结
2014/11/18 职场文书
法定授权委托证明书
2015/06/18 职场文书
小学大队干部竞选稿
2015/11/20 职场文书
PHP实现两种排课方式
2021/06/26 PHP