在WEB上,如果用到表格,大家估计一般用的都是EXT或者JQuery的组件,但我在做的是一个复杂报表的WEB展现器,不想使用组件,于是,很多东西需要自已实现,这不,需要添加行头,列头锁定的功能。想起来好象很困难,但实际上并不难。需要注意以下几点:
1:固定行头,列头,实际上主要是要处理横纵向滚动条的问题。
2:基于1,我们需要为TABLE提供一个DIV,并且div必须有:overflow:auto,也就是把滚动条打开。
3:行头,列头实际上就是一些 TD 元素,因为要考虑交叉单元,即是行锁又是列锁,所以还要考虑最特殊的左上角单元,而锁定的意思,也就是它们不随滚动条的位置而变动位置。
4:基于3,我们认为行头锁定,也就是固定行头单元的left位置,列头也就是固定top位置。
5:我们知道有两个属性:srollleft scrolltop ,它们表达的是滚动后的相对位置,如果我们把滚动后的相对位置赋给单元格的本身位置,那就达到锁定的效果了。
这里是关键,可能我没说清楚,但不要紧,你只要看下面的例子就明白了。
<html>
<head>
<title>表格行列锁定的示例</title>
<script>
function test()
{
var _this = window.event.srcElement;
alert("scrollTop: " + _this.parentNode.offsetParent.parentNode.scrollTop);
alert("scrollLeft: " + _this.parentNode.offsetParent.parentNode.scrollLeft);
}
</script>
</head>
<body>
<div style="overflow:auto;width:300px;height:300px;">
<table border=1 style="position:absolute;">
<tbody>
<tr height=20>
<td class="CLock" οnclick="test()">xxx</td>
<td class="VLock" οnclick="test()">HEADING_A</td>
<td class="VLock">HEADING_B</td>
<td class="VLock">HEADING_C</td>
<td class="VLock">HEADING_D</td>
<td class="VLock">HEADING_E</td>
</tr>
<tr height=100>
<td class="HLock" οnclick="test()">1</td>
<td>A1</td>
<td>B1</td>
<td>C1</td>
<td>D1</td>
<td>E1</td>
</tr>
<tr height=100>
<td class="HLock">2</td>
<td>A2</td>
<td>B2</td>
<td>C2</td>
<td>D2</td>
<td>E2</td>
</tr>
<tr height=100>
<td class="HLock">3</td>
<td>A3</td>
<td>B3</td>
<td>C3</td>
<td>D3</td>
<td>E3</td>
</tr>
<tr height=100>
<td class="HLock">4</td>
<td>A4</td>
<td>B4</td>
<td>C4</td>
<td>D4</td>
<td>E4</td>
</tr>
<tr height=100>
<td class="HLock">5</td>
<td>A5</td>
<td>B5</td>
<td>C5</td>
<td>D5</td>
<td>E5</td>
</tr>
</tbody>
</table>
</div>
<style>
td.HLock
{
z-index: 10;
position: relative;
left: expression(this.parentNode.offsetParent.parentNode.scrollLeft );
background: blue;
}
td.VLock
{
z-index: 20;
position: relative;
top: expression(this.parentNode.offsetParent.parentNode.scrollTop );
background: red;
}
td.CLock
{
z-index: 30;
position: relative;
top: expression(this.parentNode.offsetParent.parentNode.scrollTop );
left: expression(this.parentNode.offsetParent.parentNode.scrollLeft );
background: green;
}
</style>
</body>
</html>
好了,上面例子里最关键的就是 top和left的计算,首先,expression是什么,大家应该清楚。而td的parentNode也就是tr,offsetParent也就是table,table的parentNode就是div了。其它不多说了。(如果还不明白这个关系,可以看看我上面写的test函数,实际上可以看到效果).
CSS功能很强大,但也没什么规距可循,不易于学习,希望在HTML5和CSS3中有改进。
不过,我试了一下firefox,好象无效,现在没空整,有空改进一下。