花了两个晚上的时间,终于搞定了固定表头功能。
先上效果图(注:有背景图和灰色的行、列为固定的表头行和左边列,背景图是表格原有的样式,不是固定表头后添加的)
指定要固定的行数和列数,兼容各浏览器,固定后的表头和左边列的样式外观完全复制原来的表格样式。
可以设置固定整个表头,即Table中有设置了
,可以固定整个thead;也可以按指定的行数固定。有一种情况不可以启用左边列固定,即当表头行中的相应的列的单元格有合并单元格的情况下,不可以启用左边表固定。
如果要固定左边的列,则相应的表头不应有合并单元格,且要固定的列必须设置宽度,比如要固定左边第一列和第二列,则第一列和第二列需要设置宽度,截图中的为80像素宽度,即 style="width:80px;"
对于一些复杂的多层表头可能会有错位现象,以后有时间了再修改。

图1

图2

图3

图4
(注:要固定的左边列的表头单元格不能有合并单元格)
原生JS代码,代码并不多,153行代码。
var ofixed_table_st = window.setTimeout;
window.setTimeout = function(fRef, mDelay) {
if (typeof fRef == 'function') {
var argu = Array.prototype.slice.call(arguments, 2);
var f = (function() {
fRef.apply(null, argu);
});
return ofixed_table_st(f, mDelay);
}
return ofixed_table_st(fRef, mDelay);
};
function oFixedTable(id, obj, _cfg){
this.id = id;
this.obj = obj;
this.box = this.obj.parentNode;
this.config = {
fixHead: _cfg.fixHead || true,
rows: _cfg.rows || 1,
cols: _cfg.cols || 0,
background: _cfg.background || '#f1f1f1',
zindex: _cfg.zindex || 9999
};
window.setTimeout(this._fixTable, 100, this);
}
oFixedTable.prototype._fixTable = function(_){
if(_.obj.rows.length <= 0){
return false;
}
var hasLeft = _.buildLeft();
var hasHead = _.buildHead();
_.box.onscroll = function(){
if(_.divHead != null){
_.divHead.scrollLeft = this.scrollLeft;
}
if(_.divLeft != null){
_.divLeft.scrollTop = this.scrollTop;
}
};
if(hasHead && hasLeft){
_.buildTopLeft();
}
};
oFixedTable.prototype.buildHead = function(){
var _ = this;
var strDivId = _.id + '_div_head';
var strTbId = _.id + '_tb_header';
var div = document.createElement('div');
div.id = strDivId;
div.style.cssText = 'position:absolute;overflow:hidden;z-index:' + (_.config.zindex + 1) + ';';
div.innerHTML = '
';_.box.insertBefore(div, _.obj);
_.divHead = div;
_.tbHead = document.getElementById(strTbId);
//判断是否出现纵向滚动条,若出现,高度减去滚动条宽度 16px
var sw = _.obj.offsetHeight > _.box.offsetHeight ? 16 : 0;
_.divHead.style.width = (_.box.offsetWidth - sw) + 'px';
_.tbHead.style.textAlign = _.obj.style.textAlign;
_.tbHead.style.width = _.obj.offsetWidth + 'px';
var hasHead = false;
if(_.config.fixHead && _.obj.tHead != null){
var tHead = _.obj.tHead;
_.tbHead.appendChild(tHead.cloneNode(true));
hasHead = true;
} else {
for(var i=0; i<_.config.rows i>
var row = _.obj.rows[i];
if(row != null){
_.tbHead.appendChild(row.cloneNode(true));
hasHead = true;
}
}
}
return hasHead;
};
oFixedTable.prototype.buildLeft = function(){
var _ = this;
if(_.config.cols <= 0){
return false;
}
var strDivId = _.id + '_div_left';
var strTbId = _.id + '_tb_left';
var div = document.createElement('div');
div.id = strDivId;
div.style.cssText = 'position:absolute;overflow:hidden;z-index:' + _.config.zindex + ';';
div.innerHTML = '
';_.box.insertBefore(div, _.obj);
_.divLeft = div;
_.tbLeft = document.getElementById(strTbId);
_.tbLeft.style.textAlign = _.obj.style.textAlign;
//判断是否出现横向滚动条,若出现,高度减去滚动条高度 16px
var sw = _.obj.offsetWidth > _.box.offsetWidth ? 16 : 0;
_.divLeft.style.height = (_.box.offsetHeight - sw) + 'px';
var hasLeft = false;
for(var i=0,rows=_.obj.rows.length; i
var row = _.tbLeft.insertRow(_.tbLeft.rows.length);
row.style.cssText = _.obj.rows[i].style.cssText;
for(j=0; j<_.config.cols j>
var cell = _.obj.rows[i].cells[j];
if(cell != null){
row.appendChild(cell.cloneNode(true));
cell.style.cssText = _.obj.rows[i].cells[j].style.cssText;
hasLeft = true;
}
}
}
return hasLeft;
};
oFixedTable.prototype.buildTopLeft = function(){
var _ = this;
var strDivId = _.id + '_div_top_left';
var strTbId = _.id + '_tb_top_left';
var div = document.createElement('div');
div.id = strDivId;
div.style.cssText = 'position:absolute;overflow:hidden;z-index:' + (_.config.zindex + 2) + ';';
div.innerHTML = '
';_.box.insertBefore(div, _.obj);
var tbTopLeft = document.getElementById(strTbId);
tbTopLeft.style.textAlign = _.obj.style.textAlign;
for(var i=0; i<_.config.rows i>
var row = tbTopLeft.insertRow(tbTopLeft.rows.length);
row.style.cssText = _.obj.rows[i].style.cssText;
for(j=0; j<_.config.cols j>
var cell = _.obj.rows[i].cells[j];
if(cell != null){
row.appendChild(cell.cloneNode(true));
cell.style.cssText = _.obj.rows[i].cells[j].style.cssText;
hasLeft = true;
}
}
}
};
调用代码很简单,只需要一句代码, HTML页面及调用示例:
无标题页body{font-size:12px;}
table{border:solid 1px #ccc; border-collapse:collapse;}
table td,table th{border:solid 1px #ccc; line-height:22px; height:22px; padding:0;}
#tbheader td{background:#fff;}
固定表头、固定左边单元格 示例:
本文介绍了一种使用原生JS实现固定HTML表头和左侧列的方法,适用于兼容各浏览器。通过创建克隆元素并设置定位,实现了在滚动时保持表头和左侧列固定的效果。代码简洁,共153行。示例代码展示了如何调用该功能。
2万+

被折叠的 条评论
为什么被折叠?



