<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=gb2312"> <title>固定表头和列</title> <style> .FixedTitleRow { position: relative; top: expression(this.offsetParent.scrollTop); z-index: 10; background-color: #E6ECF0; } .FixedTitleColumn { position: relative; left: expression(this.parentElement.offsetParent.scrollLeft); } .FixedDataColumn { position: relative; left: expression(this.parentElement.offsetParent.parentElement.scrollLeft); background-color: #E6ECF0; } </style> </head> <body> <div id="scrollDiv" style="width: 400px; overflow: auto; cursor: default; display: inline; position: absolute; height: 200px;"> <table id='accountTable' width='550' height='230' cellpadding='0' cellspacing='0' border='1' style='table-layout: auto' bordercolor='lightgrey'> <tbody> <tr class="FixedTitleRow"> <td class="FixedTitleColumn"> ID0</td> <td class="FixedTitleColumn"> CK0</td> <td class="FixedTitleColumn"> Code0</td> <td class="FixedTitleColumn"> Descirption0</td> <td class="FixedTitleColumn"> TOL0</td> <td> XS0</td> <td > SS0</td> <td> MS0</td> <td> DS0</td> <td> BS0</td> <td> XL0</td> <td> ML0</td> <td> DL0</td> <td> EM0</td> <td> BM0</td> </tr> <tr> <td class="FixedDataColumn"> 88</td> <td class="FixedDataColumn"> 88</td> <td class="FixedDataColumn"> 88</td> <td class="FixedDataColumn"> 88</td> <td class="FixedDataColumn"> 88</td> <td> 22</td> <td> 22</td> <td> 22</td> <td> 22</td> <td> 22</td> <td> 22</td> <td> 22</td> <td> 22</td> <td> 22</td> <td> 22</td> </tr> <tr> <td class="FixedDataColumn"> 111</td> <td class="FixedDataColumn"> 111</td> <td class="FixedDataColumn"> 1111</td> <td class="FixedDataColumn"> This is Test</td> <td class="FixedDataColumn"> 1</td> <td> 001</td> <td> 002</td> <td> 003</td> <td> 004</td> <td> 005</td> <td> 006</td> <td> 007</td> <td> 008</td> <td> 009</td> <td> 010</td> </tr> <tr> <td class="FixedDataColumn"> 111</td> <td class="FixedDataColumn"> 111</td> <td class="FixedDataColumn"> 1111</td> <td class="FixedDataColumn"> This is Test</td> <td class="FixedDataColumn"> 1</td> <td> 001</td> <td> 002</td> <td> 003</td> <td> 004</td> <td> 005</td> <td> 006</td> <td> 007</td> <td> 008</td> <td> 009</td> <td> 010</td> </tr> <tr> <td class="FixedDataColumn"> 111</td> <td class="FixedDataColumn"> 111</td> <td class="FixedDataColumn"> 1111</td> <td class="FixedDataColumn"> This is Test</td> <td class="FixedDataColumn"> 1</td> <td> 001</td> <td> 002</td> <td> 003</td> <td> 004</td> <td> 005</td> <td> 006</td> <td> 007</td> <td> 008</td> <td> 009</td> <td> 010</td> </tr> <tr> <td class="FixedDataColumn"> 111</td> <td class="FixedDataColumn"> 111</td> <td class="FixedDataColumn"> 1111</td> <td class="FixedDataColumn"> This is Test</td> <td class="FixedDataColumn"> 1</td> <td> 001</td> <td> 002</td> <td> 003</td> <td> 004</td> <td> 005</td> <td> 006</td> <td> 007</td> <td> 008</td> <td> 009</td> <td> 010</td> </tr> </tbody> </table> </div> </body> </html>
通过样式表来实现固定表头和列。效果确实不错。但是对于其中的疑问和问题这里需要补充一下。原文中设了三个样式,FixedTitleRow标题行(TR) 的样式,FixedTitleColumn标题列(TD)的样式及FixedDataColumn数据列(TD)的样式;在这三种样式中都统一设置 position属性为relative,这个设置是非常重要的,relative的解释说明是这样的:
Setting the property to relative places the object in the natural HTML flow of the document, but offsets the position of the object based on the preceding content. (设置HTML文档中的对象属性为relative时,其位移是相对于前面内容对象的)
也就是说那些固定列头的位置(left,top)是在当前所在的位置的基础上偏移的,其偏移量就是在样式中设置的left或top属性值。例如偏移量是10,则当前列头的位置则向右偏移10个象素,如果是-10,则向左偏移10个象素;所以在样式中可以看到下面的代码:
其作用就是将当前TABLE所属的DIV的滚动条的偏移位置(top,left)付给固定列头的left或top属性,这样当滚动条拖动时,固定列头就不会随之移动啦!这也是样式的expression强大之处,它可以在运行时实时计算left和top值而不需要我们写一句代码。如果真要用JS代码来实现此功能,估计没百把行是不可能完成的,并且实现起来也不是那么容易。
另外一个感到疑惑的是在样式expression表达式中,又是this.parentElement,又是this.offsetParent,觉得有点乱。其实都是为了得到TABLE所属的DIV对象,但我很少用parentElement属性,如果想要以document层次树更清晰的表达,推荐用 parentNode。所以我对原文中的expression改成了如下形式:是不是比以前的表达式清晰?!呵呵,在上面需要注意一点的就是TR的parentNode是TBODY,就算你TABLE中没有写<TBODY>,它也是隐藏的。所以TR追溯到DIV需要3级,TD则需要4级;
.FixedTitleRow {...}{ position: relative; top: expression(this.parentNode.parentNode.parentNode.scrollTop); z-index: 10; background-color: #E6ECF0; } .FixedTitleColumn {...}{ position: relative; left: expression(this.parentNode.parentNode.parentNode.parentNode.scrollLeft); } .FixedDataColumn {...}{ position: relative; left: expression(this.parentNode.parentNode.parentNode.parentNode.scrollLeft); background-color: #E6ECF0; }
在你将上面的示例代码准备运用到你的项目中时,请注意如下几点: