3、双表头固定的数据列表中,滚动条同步移动的实现
l 问题:Web中单表头固定的数据列表使用比较多,其滚动条移动的实现很简单,只要使用<DIV>标记,设置其的样式就可以了。但有时也需要使用双表头固定的数据列表,典型的例子就是人员的日程安排。
l 解决方法:分别用三个<DIV>标记包含上表头(topheader),左表头(leftheader)和数据内容(content),只有content有滚动条;当移动滚动条时(产生onscroll事件),设置topheader的scrollLeft属性以及leftheader 的scrollTop属性,使其和content保持一致。
l 下面是一个实现例子的核心代码片断,做一下简单说明,源代码可以在这里下载。
<style TYPE="text/css">
<!--
div.topheader {
width: 840px;
height: 30px;
margin-top: 0;
margin-bottom: 0;
margin-left: 0;
overflow: scroll;
overflow-x: hidden;
overflow-y: hidden;
}
div.leftheader {
width: 120px;
height: 422px;
margin-top: 0;
margin-bottom: 0;
overflow: scroll;
overflow-x: hidden;
overflow-y: hidden;
word-break: break-all
}
div.content {
width: 856px;
height: 439px;
margin-top: 0;
margin-bottom: 0;
margin-left: 0;
overflow: scroll;
overflow-x: auto;
overflow-y: auto;
word-break: break-all
}
table.topheader {
width: 2520;
}
th.t1 {
width: 78;
height: 24;
}
table.leftheader {
width: 120;
}
td.l1 {
width: 120;
height: 70;
}
table.content {
width: 2520;
}
td.c1 {
width: 84;
height: 70;
}
-->
</style>
<script type="text/javascript">
function hasAttribute(object, attrName) {
if (typeof object !== "object" && typeof object !== "string") {
return false;
}
return attrName in object;
}
function syncScroll(topId, leftId, contentId) {
var topHeader = document.getElementById(topId);
var leftHeader = document.getElementById(leftId);
var content = document.getElementById(contentId);
if (topHeader && hasAttribute(topHeader, 'scrollLeft') && content && hasAttribute(content, 'scrollLeft')) {
topHeader.scrollLeft=content.scrollLeft;
}
if (leftHeader && hasAttribute(leftHeader, 'scrollTop') && content && hasAttribute(content, 'scrollTop')) {
leftHeader.scrollTop=content.scrollTop;
}
}
</script>
l 先来看三个<DIV>标记的样式:
Ø overflow: scroll表示当<DIV>标记中的内容溢出时可以滚动
Ø topheader和leftheader的overflow-x及overflow-y属性设置为hidden,表示溢出时不显示滚动条,而content设置为auto
Ø content的width值比topheader的大16px,而height值比leftheader的大17px;这是为滚动条预留的(滚动条大概16-17px,根据具体 情况微调)
Ø word-break: break-all用来保证数据过长时自动换行,以免将单元格宽度撑大而错位
l topheader和content内部包含的<TABLE>的width设置为绝对大小,并大于对应<DIV>的width,以便出现水平滚动条
l syncScroll()函数在onscroll事件触发时调用,使topheader的scrollLeft属性以及leftheader 的scrollTop属性和content的保持同步
l 上面的例子个静态页面,在实际应用中通常是动态页面,需要注意以下一些方面:
Ø 显示的列数不定时(例如每个月的天数有所不同),需要动态计算<TABLE>的width值
Ø 当content内部包含的<TABLE>的width值<=topheader的width值(不出水平滚动条)时,content的width值要去掉滚动条大小值
Ø 同样,当content内部包含的<TABLE>的height值<= leftheader的width值(不出垂直滚动条)时,content的height值要去掉滚动条大小值
Ø word-break: break-all保证了单元格宽度不会撑大;但当单元格内容显示不下时,会自动撑大宽度,所以当表格的行距不同时,要动态计算以决定是否要出垂直滚动条,这个要麻烦一些