1、js+div
其实基本思路跟方法2是一样的,只是更进一步,不在用table了,直接用div替代table来显示数据。
这样做的主要好处是,可以比较方便的把它扩展成一个Grid widget,由于不使用table了,不用再维护一套操作table DOM的代码。因为行都是用div拼成的,增加排序、列宽调整、直接编辑等功能都会方便一点。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>表格头行固定:使用js和div实现</title>
<style>
.table{
position:relative;
overflow:hidden;
border:black 1px solid;
BACKGROUND: #F8F9FC;
z-index:10;
}
.title /* 表头行 */{
position:relative;
overflow:hidden;
z-index:10;
}
.title span{
BORDER-RIGHT: #555 1px solid;
BORDER-TOP: #fff 1px solid;
BORDER-BOTTOM: #555 1px solid;
BORDER-LEFT: #fff 1px solid;
padding:2 1 2 2;
BACKGROUND: #ccc;
overflow:hidden;
WHITE-SPACE: nowrap;
position:relative;
display:inline-block;
}
.content /* 内容区 */{
position:relative;
overflow:hidden;
}
.content span{
BORDER-RIGHT: #555 1px solid;
BORDER-TOP: #fff 1px solid;
BORDER-BOTTOM: #555 1px solid;
BORDER-LEFT: #fff 1px solid;
padding:2 1 2 2;
overflow:hidden;
WHITE-SPACE: nowrap;
position:relative;
display:inline-block;
}
.vscroll{
position:absolute;
right:0px;
top:0px;
height:100%;
width:10px;
background:#f1f1f1;
border:#CCF 1px solid;
overflow:hidden;
z-index:10;
}
.hscroll{
position:absolute;
bottom:0px;
left:0px;
height:10px;
width:100%;
background:#f1f1f1;
border:#CCF 1px solid;
overflow:hidden;
z-index:10;
}
.vglide /* 滑块样式 */{
position:absolute;
z-index:10;
top:0px;
left:0px;
width:100%;
height:20px;
overflow:hidden;
background:#666666
}
.hglide /* 滑块样式 */{
position:absolute;
z-index:10;
top:0px;
left:0px;
width:20px;
height:100%;
overflow:hidden;
background:#666666
}
.fillbox{
position:absolute;
height:10px;
width:10px;
bottom:0px;
right:0px;
background:#f1f1f1;
border:#CCF 1px solid;
z-index:10;
}
</style>
<script type="text/javascript" src="./js/jquery-1.3.2.js"></script>
<script type="text/javascript" src="./js/jquery.mousewheel.js"></script>
<script type="text/javascript">
$(document).ready(function(){
//初始化title
var tWidth = 0;
$("#title span").each(function(i){
$(this).width("60px");
tWidth += $(this).outerWidth();
});
$("#title").width(tWidth);
//初始化content
$("#content span").each(function(i){
$(this).width("60px");
});
$("#content").width(tWidth);
//content的可视区域
var visualH = $("#table").height() - $("#title").height() - $("#hScroll").height();
var visualW = $("#table").width() - $("#vScroll").width();
//初始化滚动条和滑块尺寸
$("#vScroll").height($("#table").height() - $("#hScroll").height());
var gHeight = $("#vScroll").height()*(visualH/$("#content").height());
$("#vGlide").height(gHeight);
$("#hScroll").width($("#table").width() - $("#vScroll").width());
var gWidth = $("#hScroll").width()*(visualW/$("#content").width());
$("#hGlide").width(gWidth);
//拖拽方法
var scrolling = 0;
function StartDrag(event){scrolling=event.data.type;}
function Draging(event){
if (scrolling == 1) vScrollTo(event);
else if (scrolling == 2) hScrollTo(event);
}
//垂直滚动
function vScrollTo(event){
var event=event?event:(window.event?window.event:null);
var Y=event.clientY-$("#table").offset().top-$("#vGlide").height()/2;
if (Y > $("#vScroll").height() - $("#vGlide").height())
Y = $("#vScroll").height() - $("#vGlide").height();
if (Y < 0)
Y = 0;
var H=$("#vScroll").height();
var SH=Y/H*$("#content").get(0).scrollHeight;
$("#vGlide").css("top",Y + "px");
$("#content").css("top",-SH + "px");
}
//水平滚动
function hScrollTo(event){
var event=event?event:(window.event?window.event:null);
var X=event.clientX-$("#table").offset().left-$("#hGlide").width()/2;
if (X > $("#hScroll").width() - $("#hGlide").width())
X = $("#hScroll").width() - $("#hGlide").width();
if (X < 0)
X = 0;
var W=$("#hScroll").width();
var SW=X/W*$("#content").get(0).scrollWidth;
$("#hGlide").css("left",X + "px");
$("#content").css("left",-SW + "px");
$("#title").css("left",-SW + "px")
}
//滚轮处理
function ScrollWheel(event, delta){
var Y=$("#vGlide").position().top;
var H=$("#vScroll").height();
if (delta >= 0) {Y=Y-20;} else {Y=Y+20;}
if (Y > $("#vScroll").height() - $("#vGlide").height())
Y = $("#vScroll").height() - $("#vGlide").height();
if (Y < 0)
Y = 0;
var H=$("#vScroll").height();
var SH=Y/H*$("#content").get(0).scrollHeight;
$("#vGlide").css("top",Y + "px");
$("#content").css("top",-SH + "px");
}
//注册事件
$("#vScroll").bind("click",vScrollTo);
$("#hScroll").bind("click",hScrollTo);
$("#vGlide").bind("mousedown",{type:1},StartDrag);
$("#hGlide").bind("mousedown",{type:2},StartDrag);
$(document).bind("mousemove",Draging);
$(document).bind("mouseup",function(){scrolling=0;});
$("#table")[0].onselectstart = function(){return false;};
$("#table").bind("mousewheel",ScrollWheel);
});
</script>
</head>
<body>
<div id="table" class="table" style="width:300px;height:200px">
<div id="title" class="title">
<span>标题1</span><span>标题2</span><span>标题3</span><span>标题4</span><span>标题5</span><span>标题6</span><span>标题7</span><span>标题8</span><span>标题9</span>
</div>
<div id="content" class="content">
<div><span>内容1</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容1</span><span>内容1</span></div>
<div><span>内容2</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容2</span><span>内容2</span></div>
<div><span>内容3</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容3</span><span>内容3</span></div>
<div><span>内容4</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容4</span><span>内容4</span></div>
<div><span>内容5</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容5</span><span>内容5</span></div>
<div><span>内容6</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容6</span><span>内容6</span></div>
<div><span>内容7</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容7</span><span>内容7</span></div>
<div><span>内容8</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容8</span><span>内容8</span></div>
<div><span>内容9</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容9</span><span>内容9</span></div>
<div><span>内容10</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容10</span><span>内容10</span></div>
<div><span>内容11</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容11</span><span>内容11</span></div>
<div><span>内容12</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容12</span><span>内容12</span></div>
<div><span>内容13</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容13</span><span>内容13</span></div>
<div><span>内容14</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容14</span><span>内容14</span></div>
<div><span>内容15</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容15</span><span>内容15</span></div>
<div><span>内容16</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容16</span><span>内容16</span></div>
<div><span>内容17</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容17</span><span>内容17</span></div>
<div><span>内容18</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容18</span><span>内容18</span></div>
<div><span>内容19</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容19</span><span>内容19</span></div>
<div><span>内容20</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容20</span><span>内容20</span></div>
<div><span>内容21</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容21</span><span>内容21</span></div>
<div><span>内容22</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容22</span><span>内容22</span></div>
<div><span>内容23</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容23</span><span>内容23</span></div>
<div><span>内容24</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容24</span><span>内容24</span></div>
<div><span>内容25</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容</span><span>内容25</span><span>内容25</span></div>
</div>
<div id="hScroll" class="hscroll"><div id="hGlide" class="hglide"></div></div>
<div id="vScroll" class="vscroll"><div id="vGlide" class="vglide"></div></div>
<div class="fillbox"></div>
</div>
</body>
</html>
2.js+table
1、使用js生成一个新的标题行,放在一个div中做为一个新表头。新建的表头,可以使用div内嵌span的方式来模拟;也可直接建一个新的table
2、将原table,放在另一个div中,同时删除表头
3、增加js代码,保持table在水平滚动时,新表头的div也会随着一起移动,保证表头和列的位置始终一致,整个表格被分到2个div中,一个放表头,一个放table。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>表格头行固定:使用js和table实现</title>
<style type=text/css>
.griddiv{
overflow-x:hidden;
border:black 1px solid;
BACKGROUND: #F8F9FC;
position:relative;
}
.title /* 新建表头样式 */{
BORDER-RIGHT: #555 1px solid;
BORDER-TOP: #fff 1px solid;
BORDER-BOTTOM: #555 1px solid;
BORDER-LEFT: #fff 1px solid;
padding:2 1 2 2;
BACKGROUND: #ccc;
CURSOR: hand;
Font-Size:9pt;
overflow:hidden;
WHITE-SPACE: nowrap;
position:relative;
display:inline-block;
}
td{
WHITE-SPACE: nowrap;
BORDER: #ddd 1px solid;
}
.cdata {
padding:1 1 1 2;
Font-Size:9pt;
}
</style>
</head>
<body>
<div class='griddiv' id='griddiv'>
<div id="titlediv" style='position:relative;BACKGROUND: red'></div>
<div id="tablediv" style='overflow-x:scroll;overflow-y:scroll' οnscrοll='SYNC_Roll(this)'>
<table id="tb" width='100%' border="0" cellpadding="0" cellspacing="0">
<tr id="titletr"><td>标题1</td><td>标题2</td><td>标题3</td></tr>
<tr class='cdata'><td>内容内容1内容1内容1内容1内容1内容11</td><td>内容22222222222222222222222222222</td><td>内容3内容3内容3内容3内容3内容3内容3内容3内容3内容3内容3内容3内容3内容3</td></tr>
<tr class='cdata'><td>内容1</td><td>内容2</td><td>内容3</td></tr>
<tr class='cdata'><td>内容1</td><td>内容2</td><td>内容3</td></tr>
<tr class='cdata'><td>内容1</td><td>内容2</td><td>内容3</td></tr>
<tr class='cdata'><td>内容1</td><td>内容2</td><td>内容3</td></tr>
<tr class='cdata'><td>内容1</td><td>内容2</td><td>内容3</td></tr>
<tr class='cdata'><td>内容1</td><td>内容2</td><td>内容3</td></tr>
<tr class='cdata'><td>内容1</td><td>内容2</td><td>内容3</td></tr>
<tr class='cdata'><td>内容1</td><td>内容2</td><td>内容3</td></tr>
<tr class='cdata'><td>内容1</td><td>内容2</td><td>内容3</td></tr>
<tr class='cdata'><td>内容1</td><td>内容2</td><td>内容3</td></tr>
<tr class='cdata'><td>内容1</td><td>内容2</td><td>内容3</td></tr>
<tr class='cdata'><td>内容1</td><td>内容2</td><td>内容3</td></tr>
<tr class='cdata'><td>内容1</td><td>内容2</td><td>内容3</td></tr>
<tr class='cdata'><td>内容1</td><td>内容2</td><td>内容3</td></tr>
<tr class='cdata'><td>内容1</td><td>内容2</td><td>内容3</td></tr>
<tr class='cdata'><td>内容1</td><td>内容2</td><td>内容3</td></tr>
<tr class='cdata'><td>内容1</td><td>内容2</td><td>内容3</td></tr>
<tr class='cdata'><td>内容1</td><td>内容2</td><td>内容3</td></tr>
<tr class='cdata'><td>内容1</td><td>内容2</td><td>内容3</td></tr>
<tr class='cdata'><td>内容1</td><td>内容2</td><td>内容3</td></tr>
<tr class='cdata'><td>内容1</td><td>内容2</td><td>内容3</td></tr>
<tr class='cdata'><td>内容1</td><td>内容2</td><td>内容3</td></tr>
<tr class='cdata'><td>内容1</td><td>内容2</td><td>内容3</td></tr>
<tr class='cdata'><td>内容1</td><td>内容2</td><td>内容3</td></tr>
<tr class='cdata'><td>内容1</td><td>内容2</td><td>内容3</td></tr>
</table>
</div>
</div>
<script language=javascript>
var gdiv=document.getElementById("griddiv"); //最外层的div
var titdiv=document.getElementById("titlediv"); //新建表头的div
var tbdiv=document.getElementById("tablediv"); //包裹table的div
var tb=document.getElementById("tb"); //table
var tr=document.getElementById("titletr"); //table内的表头
//创建新的表头,同时删除原来table中的表头
function createtitle(tdiv,ttb,ttr){
tdiv.style.width=ttb.clientWidth+"px";
var newtit="";
for(i=0;i<ttr.cells.length;i++)
{
var ttd=ttr.cells[i];
newtit=newtit+"<span class='title' style='width:"+(ttd.clientWidth)+"px'>"+ttd.childNodes[0].nodeValue+"</span>"
}
tdiv.innerHTML=newtit;
//删除原表头
if (ttr.rowIndex!=ttb.rows.length-1)
ttb.deleteRow(ttr.rowIndex);
}
//使新建表头div,随水平滚动条滚动
function SYNC_Roll(obj){
titdiv.style.left=-obj.scrollLeft+"px";
}
function SetGrid(awidth,aheight){
gdiv.style.width=awidth + "px";
tbdiv.style.width=awidth + "px";
tbdiv.style.height=aheight + "px";
createtitle(titdiv,tb,tr);
}
SetGrid(500,300);
</script>
</body>
</html>
3、css+table
在table外面套个div限制显示大小,同时设置表头单元格的样式为
position: relative;
top: expression(document.getElementById("div").scrollTop);
其中express是IE自带的CSS属性,可以在CSS中调用js代码。
这里通过express中的js可以让单元格总是固定在div的最上部,不随垂直滚动条滚动。
类似的-也可以设置left: expression(document.getElementById("div").scrollLeft),来冻结某一列不随水平滚动条滚动。当然若同时设置left和top样式,则这些单元格始终不会滚动。
说明:
1、使用express来做表头固定,是最简单的,只需CSS即可,且可以支持多表头和列固定的情况
2、express是IE自带的CSS属性,在其他浏览器上都不支持;据网上的资料,express的执行效率可能有问题,鼠标移动时都会触发对应的js代码。使用需慎重!
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>表格头行固定:使用CSS实现</title>
<style type="text/css" >
div.DivContainer /* Div */{
overflow: scroll;
border: solid 1px gray;
}
table {
border-collapse: collapse;
border:solid 1px gray;
}
td {
position: relative;
padding: 5px;
border-top: solid 0px gray;
border-bottom: solid 1px gray;
border-left: solid 0px gray;
border-right: solid 1px gray;
}
td.HLocked /*左侧冻结的列*/ {
z-index: 10;
position: relative;
left: expression(document.getElementById("div").scrollLeft);
text-align: center;
BORDER-RIGHT: #555 1px solid;
BORDER-TOP: #fff 1px solid;
BORDER-BOTTOM: #555 1px solid;
BORDER-LEFT: #fff 1px solid;
padding:2 1 2 2;
BACKGROUND: #ccc;
}
td.VLocked /*垂直固定的表头*/ {
z-index: 20;
position: relative;
top: expression(document.getElementById("div").scrollTop);
color: black;
text-align: center;
BORDER-RIGHT: #555 1px solid;
BORDER-TOP: #fff 1px solid;
BORDER-BOTTOM: #555 1px solid;
BORDER-LEFT: #fff 1px solid;
padding:2 1 2 2;
BACKGROUND: #ccc;
}
td.Locked /*垂直、水平都固定的表头*/ {
z-index: 30;
position: relative;
top: expression(document.getElementById("div").scrollTop);
left: expression(document.getElementById("div").scrollLeft);
color: black;
text-align: center;
BORDER-RIGHT: #555 1px solid;
BORDER-TOP: #fff 1px solid;
BORDER-BOTTOM: #555 1px solid;
BORDER-LEFT: #fff 1px solid;
padding:2 1 2 2;
BACKGROUND: #ccc;
}
</style>
</head>
<body>
<div id="div" class="DivContainer" style="width: 400px; height: 250px;">
<table>
<tr>
<td class="Locked" colspan="4">Locked</td>
<td class="VLocked">VLocked</td>
<td class="VLocked">VLocked</td>
<td class="VLocked" rowspan="3">VLocked</td>
<td class="VLocked" rowspan="3">VLocked</td>
</tr>
<tr>
<td class="Locked" colspan="2">Locked</td>
<td class="Locked" colspan="2">Locked</td>
<td colspan="2" class="VLocked"> </td>
</tr>
<tr>
<td class="Locked">Locked</td>
<td class="Locked">Locked</td>
<td class="Locked">Locked</td>
<td class="Locked">Locked</td>
<td class="VLocked"> </td>
<td class="VLocked"> </td>
</tr>
<tr>
<td class="HLocked">HLocked</td>
<td class="HLocked">HLocked</td>
<td class="HLocked">HLocked</td>
<td class="HLocked">HLocked</td>
<td>12</td>
<td>13</td>
<td>14</td>
<td>15</td>
</tr>
<tr>
<td class="HLocked">HLocked</td>
<td class="HLocked">HLocked</td>
<td class="HLocked">HLocked</td>
<td class="HLocked">HLocked</td>
<td>22</td>
<td>23</td>
<td>24</td>
<td>25</td>
</tr>
<tr>
<td class="HLocked">HLocked</td>
<td class="HLocked">HLocked</td>
<td class="HLocked">HLocked</td>
<td class="HLocked">HLocked</td>
<td>32</td>
<td>33</td>
<td>34</td>
<td>35</td>
</tr>
<tr>
<td class="HLocked">HLocked</td>
<td class="HLocked">HLocked</td>
<td class="HLocked">HLocked</td>
<td class="HLocked">HLocked</td>
<td>42</td>
<td>43</td>
<td>44</td>
<td>45</td>
</tr>
<tr>
<td class="HLocked">HLocked</td>
<td class="HLocked">HLocked</td>
<td class="HLocked">HLocked</td>
<td class="HLocked">HLocked</td>
<td>52</td>
<td>53</td>
<td>54</td>
<td>55</td>
</tr>
<tr>
<td class="HLocked">HLocked</td>
<td class="HLocked">HLocked</td>
<td class="HLocked">HLocked</td>
<td class="HLocked">HLocked</td>
<td>62</td>
<td>63</td>
<td>64</td>
<td>65</td>
</tr>
<tr>
<td class="HLocked">HLocked</td>
<td class="HLocked">HLocked</td>
<td class="HLocked">HLocked</td>
<td class="HLocked">HLocked</td>
<td>72</td>
<td>73</td>
<td>74</td>
<td>75</td>
</tr>
<tr>
<td class="HLocked">HLocked</td>
<td class="HLocked">HLocked</td>
<td class="HLocked">HLocked</td>
<td class="HLocked">HLocked</td>
<td>82</td>
<td>83</td>
<td>84</td>
<td>85</td>
</tr>
</table>
</div>
</body>
</html>