小厂,用的开源birt做报表,不太符合用户对报表的操作习惯。
用户对报表希望:
- 自定义显示、隐藏列;
- 自定义报表列的显示顺序;
- 自定义报表列宽度;
- 按用户选择的列对表格数据排序
- 冻结表头
所有冻结表头,都是把表头元素设置成绝对定位,在页面滚动的时候,根据滚动值修正元素top值。
冻结表头的实现1:普通列表的表头冻结
结表头的实现2:单层交叉列表的表头冻结---交叉表头固定的情况
结表头的实现3:单层交叉列表的表头冻结---交叉表头是动态的
结表头的实现4:单层交叉列表的表头冻结---多层交叉表
这种情况,把表头区分为固定区,固定区,固定区表头按固定区的方式处理
动态区表头,需要分行处理
冻结表头的实现1:
原理:把table header 设置成绝对定位。然后,在滚动事件中,动态修改top值即可。
但是,设置成绝对定位后,由于元素脱离了原来的流。宽度缩小了,因此,代码中,要动态设置每列的宽度。
截图如下:
(简单设置绝对定位的效果)
HTML/CSS里面的绝对定位是脱离标准文档流的吗?
是的,绝对定位和浮动都脱离了标准文档流,但是相对定位并没有脱离;
首先要解决脚本放什么地方的问题,其次要如何识别表头。
脚本放什么位置?上图说明
(前端代码位置)
识别表头?就是设置表头id
(设置表头id的位置)
表头宽度设置,代码我考虑3种方式:
1、把table 设置position属性,把表头设置为相对定位,这样做的好处是不用设置表头列宽度,但这个方案测试了一把,通不过。如果把表头设置为绝对定位,就脱离原来的流u,一样会导致列宽改变。
2、把table header row 设置为绝对定位,取得整个表格的宽度?把头部宽度设成table宽度?整个测试无效果
因为获取的table的width,值为100%,而表头已经脱离流了,不受table影响,除非设置成绝对值,但预估应该是不行的,没有继续测试了。
3、获取表格的每一列宽度,设置到th当中去;
这有3种做法:
一个是从col属性当中获取;问题是birt得用原生的js获取col属性,另外,col是不是过时了?这个方法没有深入尝试。
一个是特定行,从特定行当中,取得每个单元格的宽度,设置到TH当中;这个不想尝试,觉得麻烦。
用新的属性,可以通过,但是,必须把表单布局改为固定布局,下面代码就是这种方式
<script>
function lockHeader(){
//设置表列头宽度的代码
var widthArray=new Array();
var ras=document.getElementById('ra');
var ths=ras.children;
for(var i=0;i<ths.length;i++){
console.log("i value:"+i);
if(ths[i].tagName=="TH"){
widthArray[i]=ths[i].getBoundingClientRect().width;
widthArray[i]=widthArray[i]-2;
ths[i].style.width =widthArray[i]+"px"
//有的浏览器 要设置th下的div元素宽度,建后面的ps说明
ths[i].children[0].style.width =widthArray[i]+"px"
}
}
//结束设置表列头宽度的代码
var oBtn = document.getElementById('Document');
//上边第一行的样式
document.getElementById('ra').style.lineHeight = '24px';
document.getElementById('ra').style.top = '0px';
document.getElementById('ra').style.background = '#E3E9F1';
document.getElementById('ra').style.position = "absolute";
//设置5个元素宽度
//绑定滚动
if (oBtn.attachEvent) { //IE 中
oBtn.attachEvent('onscroll',function () {
document.getElementById('ra').style.position = "absolute";
var scrolltop = document.getElementById('Document').scrollTop;
document.getElementById('ra').style.top = scrolltop+"px";
});
}else {//firefox googleChorme
oBtn.addEventListener('scroll', function () {
var scrollleft = document.getElementById('Document').scrollLeft;
var scrolltop = document.getElementById('Document').scrollTop;
//document.getElementById('ra').style。background-attachment="scroll";
if(scrolltop<25){
document.getElementById('ra').style.top = "0px";
}else{
document.getElementById('ra').style.top = scrolltop+"px";
}
}, false);
}
}
</script>
(可以直接复用的代码)
这里,必须设置行头的id
问题:当birt页面采取auto布局的时候,列宽和表格列不一致!对IE有效否,不确定
效果:
还有一个情况需要考虑:
合计行被绝对定位的元素覆盖了!因为,绝对定位的表头覆盖了第一行,解决办法,设置table的margin
上图:
(设置table的margin)
另外一种设表列宽度的代码:
var oBtn = document.getElementById('Document');
var ras=document.getElementById('ra');
var th=ras.childNodes
console.log(th);
var array=new Array();
for(var i=0;i<th.length;i++){
if(th[i].tagName=="TH"){
console.log(i);
var Y = th[i].getBoundingClientRect();
console.log(Y);
if (oBtn.addEventListener){
array.push(th[i].getBoundingClientRect().left+"-"+th[i].getBoundingClientRect().width);
}else{
array.push(th[i].getBoundingClientRect().left);
}
}else {
if (oBtn.addEventListener){
array.push(0);
}
}
}
if (oBtn.addEventListener) {
for(var i=0;i<th.length;i++){
if(th[i].tagName=="TH"){
th[i].style.position = "absolute";
th[i].style.top='7px';
console.log(array[i]);
if(array[i]!=0){
th[i].style.left = (array[i].split("-")[0]-1)+"px";
th[i].style.width = array[i].split("-")[1]+"px";
//有的浏览器 要设置th下的div元素宽度,建后面的ps说明
ths[i].children[0].style.width = array[i].split("-")[1]+"px";
}
}
}
}else{
for(var i=0;i<th.length;i++){
if(th[i].tagName=="TH"){
th[i].style.position = "absolute";
th[i].style.top='6px';
console.log(array[i]);
//if(array[i]!=0){
//Sth[i].style.left = (array[i]-1)+"px";
//}
}
}
}
但这个代码有个问题:如图:
目前还不知道怎么解决!
<script>
function lockHeader(){
var widthArray=new Array();
var tab=document.getElementById('report_table_myId');
//表格设为相对
tab.style.position="relative";
var oBtn = document.getElementById('Document');
//上边第一行的样式
document.getElementById('ra').style.lineHeight = '24px';
document.getElementById('ra').style.top = '0px';
document.getElementById('ra').style.background = '#E3E9F1';
document.getElementById('ra').style.position = "relative";
//设置5个元素宽度
//绑定滚动
if (oBtn.attachEvent) { //IE 中
oBtn.attachEvent('onscroll',function () {
document.getElementById('ra').style.position = "relative";
var scrolltop = document.getElementById('Document').scrollTop;
document.getElementById('ra').style.top = scrolltop+"px";
});
}else {//firefox googleChorme
oBtn.addEventListener('scroll', function () {
var scrollleft = document.getElementById('Document').scrollLeft;
var scrolltop = document.getElementById('Document').scrollTop;
//document.getElementById('ra').style。background-attachment="scroll";
if(scrolltop<25){
document.getElementById('ra').style.top = "0px";
}else{
document.getElementById('ra').style.top = scrolltop+"px";
}
}, false);
}
}
</script>
(第一种固定表头无效代码)
//初始化表头位置
var doc = document.getElementById('Document');
var ras=doc.getElementById('ra'); //ra 是自己定义的表头行的标签
var th=ras.childNodes
for(var i=0;i<th.length;i++){
if(th[i].tagName=="TH"){
th[i].style.position = "absolute";
th[i].style.top = '25px';
th[i].style.width = 103+"px";
th[i].style.height = 17+"px";
}
}
//绑定滚动
if (document.attachEvent) { //IE 中
document.attachEvent('onscroll',function () {
var scrollVal = document.getElementById('Document').scrollTop;
for(var i=0;i<th.length;i++){
if(th[i].tagName=="TH"){
th[i].style.position = "absolute";
th[i].style.top = scrollVal+'px';
}
} });
}else {//firefox googleChorme
doc.addEventListener('scroll', function () {
var scrollleft = document.getElementById('Document').scrollLeft;
var scrolltop = document.getElementById('Document').scrollTop;
if(scrolltop<25){
for(var i=0;i<th.length;i++){
if(th[i].tagName=="TH"){th[i].style.top = '25px';
}
}
}else{for(var i=0;i<th.length;i++){
if(th[i].tagName=="TH"){
th[i].style.top = scrolltop+"px";
}}}}, false);}
(控制滚动的核心代码)
ps:表头前端结构:
有的浏览器下,还需要设置div宽度,有个不用设置,什么原因呢,还不知道
ps:
相对定位:该元素相对于自己原有位置,偏移一定距离。相对的是自己。
绝对定位:该元素相对于其父元素,偏移一定距离。相对的是父元素,重点是这个父元素也需要是设置了position属性。从最近的父元素开始找,直到找到body位置为止。
冻结表头的实现1-1 多行固定:
先看效果:
由于客户单是c#嵌入的报表,因此必须支持IE浏览器;
悲剧的是ie 下,对表格的解释和chrome大不相同
1、IE下对tr设置位置属性position,脱离不了table!
2、margin-top也和chrome下的表现不大相同,解决办法:针对不同浏览器,js调整了一下
3、第2行曾经想用tr的left属性设置,结果,在ie下突破表格右边
想到的解决办法?把th下div设置位置属性,结果不显示!(奇怪的是在调试模式下,点击相关dom元素,就显示出来)
我一个前端同事告诉我,利用表格合并!把前面几个单元格合并!
我想:以后ie下,操作表格,优先考虑使用table 的单元格属性!
4、第一行rowspan=2的情况下,th的内容不显示,前端同事怀疑收到第2行的影响,把rowspan="1",问题解决!
代码如下:
<script>
function lockHeader(){
var _doc = document.getElementById('Document');
var _f=false;
//alert(_doc.attachEvent)
if(_doc.attachEvent){
_f=true;
}
//console.log(_f)
var _myTab = document.getElementById('mytab');
if(!_f){ //chrome browser
_myTab.style.marginTop="55px"
}
var ras=document.getElementById('ra');
var ths=ras.children;
//console.log('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1')
var _rb=document.getElementById('rb');
var _ths2=_rb.children;
var _initWidth_r1=new Array();
for(var i=0;i<ths.length;i++){
if(ths[i].tagName=="TH"){
if(_f){
_initWidth_r1[i]=ths[i].offsetWidth;
}else{
_initWidth_r1[i]=ths[i].getBoundingClientRect().width-3;
}
//console.log('22222222222222222222222222222222222222222222222222222222:'+_initWidth_r1[i])
}
}
//control second row
var _initWidth_r2=new Array();
var _initLeft_r2=new Array();
for(var i=0;i<_ths2.length;i++){
if(_ths2[i].tagName=="TH"){
if(_f){
_initWidth_r2[i]=_ths2[i].offsetWidth;
_initLeft_r2[i]=_ths2[i].offsetLeft;
}else{
_initWidth_r2[i]=_ths2[i].getBoundingClientRect().width-3;
}
//console.log('3333333333333333333333333333333333333:'+_initWidth_r2[i])
}
}
if (_f) {
//IE 中 得对th单元格中div 元素控制位置,所以不能在tr th 上设置position属性
document.getElementById('ra').style.position = "absolute";
document.getElementById('rb').style.position = "absolute"
//上边第一行的样式 如果多行固定,且單元格存在跨列,则要根据实际设置lineHeight
document.getElementById('ra').style.top = '0px';
document.getElementById('ra').style.background = '#E3E9F1';
document.getElementById('rb').style.top = '32px';
document.getElementById('rb').style.background = '#E3E9F1';
}else{
document.getElementById('ra').style.position = "absolute";
document.getElementById('rb').style.position = "absolute"
//上边第一行的样式 如果多行固定,且單元格存在跨列,则要根据实际设置lineHeight
document.getElementById('ra').style.top = '0px';
document.getElementById('ra').style.background = '#E3E9F1';
document.getElementById('rb').style.top = '32px';
//document.getElementById('rb').style.background = '#E3E9F1';
}
//console.log("控制第一行...........")
//debugger;
//控制第一行
var ths=ras.children;
//console.log("ths..........."+ths.length)
for(var i=0;i<ths.length;i++){
if(ths[i].tagName=="TH"){
if(_f){
//IE 中 得对th单元格中set rowSpan=0
//ths[i].children[0].style.position="absolute"
//ths[i].children[0].style.top="1px"
ths[i].rowSpan='1'
}
//console.log(_initWidth_r1[i])
ths[i].children[0].style.width =_initWidth_r1[i]+"px"
ths[i].children[0].style.height ="58px"
ths[i].children[0].style.background="#E3E9F1"
}
}
//console.log("ths[10].style.verticalAlign...........")
ths[10].style.verticalAlign="text-top";
ths[11].style.verticalAlign="text-top";
ths[12].style.verticalAlign="text-top";
//console.log("控制第二行...........")
//控制第二行
if(!_f){ //对ie而言 这个方法引起整行偏移 偏移出表格了
document.getElementById('rb').style.left =ths[10].offsetLeft+"px";
}else{ //ie
//document.getElementById('rb').style.left =ths[10].offsetLeft+"px";
_ths2[0].colSpan="11";
_ths2[0].style.textAlign="right";
}
document.getElementById('rb').style.lineHeight = '24px';
for(var i=0;i<_ths2.length;i++){
if(_ths2[i].tagName=="TH"){
if(_f){ //ie
//_ths2[i].children[0].style.position="absolute";
//_ths2[i].children[0].style.left=_initLeft_r2[i]+"px"
//_ths2[i].children[0].style.zIndex=5000
}
_ths2[i].children[0].style.width =_initWidth_r2[i]+"px"
}
}
//console.log("马上绑定滚动事件...........")
//绑定滚动
if (_doc.attachEvent) { //IE 中
//console.log("马上绑定滚动事件")
_doc.attachEvent('onscroll',function () {
var scrolltop = document.getElementById('Document').scrollTop;
//console.log("----scrolltop----"+scrolltop)
if(scrolltop<25){
document.getElementById('ra').style.top = "0px";
document.getElementById('rb').style.top = "32px";
}else{
//console.log("触发滚动,",scrolltop)
document.getElementById('ra').style.top = scrolltop+"px";
document.getElementById('rb').style.top = 32+scrolltop+"px";
}
});
}else {//firefox googleChorme
_doc.addEventListener('scroll', function () {
var scrollleft = document.getElementById('Document').scrollLeft;
var scrolltop = document.getElementById('Document').scrollTop;
//document.getElementById('ra').style.background-attachment="scroll";
if(scrolltop<25){
document.getElementById('ra').style.top = "0px";
document.getElementById('rb').style.top = "32px";
}else{
document.getElementById('ra').style.top = scrolltop+"px";
document.getElementById('rb').style.top = 32+scrolltop+"px";
}
}, false);
}
}
</script>
固定表头的实现2(交叉报表固定表头):
先看效果:
思路:
1、固定每个表头的id
交叉项目的表头,同样设置固定id,办法?上图:
2、取得父元素的宽度,设置到表头上,可惜的是,还得用fixed layout
注意这里的表头,是TH标签中的<div>
document.getElementById(cell[i]).parentNode.clientWidth+'px';
详细代码如下:
<script>
var offsetLeftMoveVal2 = 55;
function lockHeader(){
//上边第一列
cell = ['13','14','15','16','17','一月','二月','三月','四月','五月','六月','七月','八月','九月','十月','十一月','十二月'];
//固定行的样式
for(i=0;i<cell.length;i++){
document.getElementById(cell[i]).style.lineHeight = '32px';
document.getElementById(cell[i]).style.top = '0px';
document.getElementById(cell[i]).style.background = '#E3E9F1';
document.getElementById(cell[i]).style.width = document.getElementById(cell[i]).parentNode.clientWidth+'px';
var oBtn = document.getElementById('Document');
if(oBtn.attachEvent){
document.getElementById(cell[i]).style.backgroundImage = document.getElementById(cell[i]).parentNode.currentStyle.backgroundImage;
document.getElementById(cell[i]).style.position = "absolute";
document.getElementById(cell[i]).style.background = '#E3E9F1';
var cellObj = document.getElementById(cell[i]);
var leftVal=cellObj.offsetLeft-offsetLeftMoveVal2;
cellObj.style.left = leftVal+'px';
}else{
document.getElementById(cell[i]).style.backgroundImage = document.defaultView.getComputedStyle
(document.getElementById(cell[i]).parentNode, null).backgroundImage;
document.getElementById(cell[i]).style.position = "absolute";
}
}
var oBtn = document.getElementById('Document');
if (oBtn.attachEvent) { //IE 中
oBtn.attachEvent('onscroll',function () {
var scrolltop = document.getElementById('Document').scrollTop;
//上边第一行
for(i=0;i<cell.length;i++){
document.getElementById(cell[i]).style.top = scrolltop+"px";
document.getElementById(cell[i]).style.background = '#E3E9F1';
}
});
}else {//firefox googleChorme
oBtn.addEventListener('scroll', function () {
var scrolltop = document.getElementById('Document').scrollTop;
//上边第一行
for(i=0;i<cell.length;i++){
document.getElementById(cell[i]).style.top = scrolltop+"px";
document.getElementById(cell[i]).style.background = '#E3E9F1';
}
//上边第二行
}, false);
}
}
</script>
问题:这里我是知道动态列就是月份名称的,还有不知道动态的怎么办,看固定表头的实现3(交叉报表固定表头2)
固定表头的实现3(交叉报表固定表头2):
先看完成的效果:
解决的思路:
1 设法防取得取得动态的列名
2 web 页面渲染的时候,动态改变每个列的width 等样式
<script>
function lockHeader()
{
//动态适配数组,'placeHolder' 会被替换为'甲银行',‘乙银行’,....
var _DynAdapters = ['placeHolder'];
console.log("_DynAdapters"+_DynAdapters.length)
console.log("_DynAdapters o"+_DynAdapters)
//存放的交叉表动态列头
var _DynamicColHeaders = new Array();
//构造上边第二列的id
var a=0;
for(i=0;i<_DynAdapters.length;i++)
{
_DynamicColHeaders[a] = _DynAdapters[i];
a++;
}
var oBtn = document.getElementById('Document');
var _FixedColHeaders = ['1','2','3','4','5','6'];
var cellObiOne = document.getElementById(_FixedColHeaders[0]);
var leftOne = "";
var k = 0;
//左边的固定列
for(i=0;i<_FixedColHeaders.length;i++)
{
var _fixColHeader=document.getElementById(_FixedColHeaders[i]);
if(oBtn.attachEvent)
{
_fixColHeader.style.lineHeight = '28px';
_fixColHeader.style.top = '0px';
_fixColHeader.style.width = _fixColHeader.parentNode.clientWidth+'px';
_fixColHeader.style.backgroundImage = _fixColHeader.parentNode.currentStyle.backgroundImage;
_fixColHeader.style.position = "absolute";
var cellObj = _fixColHeader;
var leftVal=cellObj.offsetLeft-offsetLeftMoveVal2;
if(k == 0)
{
leftOne = cellObiOne.offsetLeft-offsetLeftMoveVal2;
k++;
}
cellObj.style.left = leftVal - leftOne +'px';
}
else
{
_fixColHeader.style.width=_fixColHeader.parentNode.clientWidth+'px';
_fixColHeader.style.backgroundImage = document.defaultView.getComputedStyle(_fixColHeader.parentNode, null).backgroundImage;
_fixColHeader.style.position = "absolute";
}
}
//右边边的动态列
for(i=0;i<_DynamicColHeaders.length;i++)
{
var colHeader=document.getElementById(_DynamicColHeaders[i]);
if(oBtn.attachEvent)
{
colHeader.style.lineHeight = '28px';
colHeader.style.top = '0px';
colHeader.style.width = colHeader.parentNode.clientWidth+'px';
colHeader.style.backgroundImage = colHeader.parentNode.currentStyle.backgroundImage;
colHeader.style.position = "absolute";
//document.getElementById(_DynamicColHeaders[i]).style.overflow = "hidden";
var cellObjTwo =colHeader;
var leftValTwo=cellObjTwo.offsetLeft-offsetLeftMoveVal2;
cellObjTwo.style.left = leftValTwo - leftOne +'px';
}
else
{
colHeader.style.backgroundImage = document.defaultView.getComputedStyle(colHeader.parentNode, null).backgroundImage;
colHeader.style.width = colHeader.parentNode.clientWidth+'px';
colHeader.style.position = "absolute";
}
}
if (oBtn.attachEvent) //IE 中
{
oBtn.attachEvent('onscroll', function ()
{
var scrolltop = document.getElementById('Document').scrollTop;
//上边第一行
for(i=0;i<_FixedColHeaders.length;i++)
{
if(scrolltop<25)
{
document.getElementById(_FixedColHeaders[i]).style.top = "0px";
}
else
{
document.getElementById(_FixedColHeaders[i]).style.top = scrolltop+"px";
}
}
//后边的动态列
for(i=0;i<_DynamicColHeaders.length;i++)
{
if(scrolltop<25)
{
document.getElementById(_DynamicColHeaders[i]).style.top = "0px";
}
else
{
document.getElementById(_DynamicColHeaders[i]).style.top = scrolltop+"px";
}
}
});
}
else //firefox googleChorme
{
oBtn.addEventListener('scroll', function ()
{
var scrolltop = document.getElementById('Document').scrollTop;
_FixedColHeaders = ['1','2','3','4','5','6'];
//左边前六列
for(i=0;i<_FixedColHeaders.length;i++)
{
document.getElementById(_FixedColHeaders[i]).style.position = "absolute";
if(scrolltop<25)
{
document.getElementById(_FixedColHeaders[i]).style.top = "0px";
}
else
{
document.getElementById(_FixedColHeaders[i]).style.top = scrolltop+"px";
}
}
//后边的动态列
for(i=0;i<_DynamicColHeaders.length;i++)
{
document.getElementById(_DynamicColHeaders[i]).style.position = "absolute";
if(scrolltop<25)
{
document.getElementById(_DynamicColHeaders[i]).style.top = "0px";
}
else
{
document.getElementById(_DynamicColHeaders[i]).style.top = scrolltop+"px";
}
}
}, false);
}
}
</script>
(web 页面渲染的时候,动态改变每个列的width 等样式)
如何在渲染页面前取得交叉列头的数据:
首先当然是取得数据,然后把取得数据转换为js的数组!
(通过计算列 获取数据?这个办法也许不是最优?完全可在设计器当中做个数据集(dataset)啊!
在脚本的块当中,通过形式上的变换,把脚本块转换为数组的办法:
1、在脚本块当中,写入 var _DynAdapters = ['placeHolder'];
2、在脚本oncreate中,进行替换
if(row["RlineOne"] != null && row["RlineOne"] != "")
{
this.text = this.text.replace("placeHolder",row["RlineOne"]);
}
截图说明:
这里还有个问题,有点动态列显示的字比较多,换行了,我想到的解决思路是:
1、调整列头的行高,配套的,要修改背景颜色等 我们用了图片,以后还是用颜色吧,这样性能会好一点?
2、把margin top设置大一点,免得覆盖下面的数据?
3、不解决,这里,我就暂时不解决这个问题吧
如何认识row["RlineOne"],textArea 设置数据源啊,把这个数据源设置成包含row的dataset就好了
操作步骤总结:
- 通过数据集设法获取动态列的数据
- 引入textArea,其类型属性设置为html 类型,写oncreate事件,写textcont脚本
- 写脚本的时候,注意区分固定列和动态列,独立列要根据实际情况处理
这里根据上述步骤,写一个完整的例子:
通过数据集设法获取动态列的数据:
数据集结果预览一下:
引入text,
设置相关属性后,写2段脚本:
<script>
function lockHeader()
{
//动态适配数组,'placeHolder' 会被替换为'甲银行',‘乙银行’,....
var _DynAdapters = ["placeHolder"];
console.log("_DynAdapters"+_DynAdapters.length)
console.log("_DynAdapters o"+_DynAdapters)
//存放的交叉表动态列头
var _DynamicColHeaders = new Array();
//构造上边第二列的id
var a=0;
for(i=0;i<_DynAdapters.length;i++)
{
_DynamicColHeaders[a] = _DynAdapters[i];
a++;
}
var oBtn = document.getElementById('Document');
var _FixedColHeaders = ['1','2','3','4','5'];
var cellObiOne = document.getElementById(_FixedColHeaders[0]);
var leftOne = "";
var k = 0;
//左边的固定列
for(i=0;i<_FixedColHeaders.length;i++)
{
var _fixColHeader=document.getElementById(_FixedColHeaders[i]);
if(oBtn.attachEvent)
{
_fixColHeader.style.lineHeight = '28px';
_fixColHeader.style.top = '0px';
_fixColHeader.style.width = _fixColHeader.parentNode.clientWidth+'px';
_fixColHeader.style.backgroundImage = _fixColHeader.parentNode.currentStyle.backgroundImage;
_fixColHeader.style.position = "absolute";
var cellObj = _fixColHeader;
var leftVal=cellObj.offsetLeft-offsetLeftMoveVal2;
if(k == 0)
{
leftOne = cellObiOne.offsetLeft-offsetLeftMoveVal2;
k++;
}
cellObj.style.left = leftVal - leftOne +'px';
}
else
{
_fixColHeader.style.width=_fixColHeader.parentNode.clientWidth+'px';
_fixColHeader.style.backgroundImage = document.defaultView.getComputedStyle(_fixColHeader.parentNode, null).backgroundImage;
_fixColHeader.style.position = "absolute";
}
}
//右边边的动态列
for(i=0;i<_DynamicColHeaders.length;i++)
{
var colHeader=document.getElementById(_DynamicColHeaders[i]);
if(colHeader==undefined) continue;
if(colHeader==null) continue;
if(oBtn.attachEvent)
{
colHeader.style.lineHeight = '28px';
colHeader.style.top = '0px';
colHeader.style.width = colHeader.parentNode.clientWidth+'px';
colHeader.style.backgroundImage = colHeader.parentNode.currentStyle.backgroundImage;
colHeader.style.position = "absolute";
//document.getElementById(_DynamicColHeaders[i]).style.overflow = "hidden";
var cellObjTwo =colHeader;
var leftValTwo=cellObjTwo.offsetLeft-offsetLeftMoveVal2;
cellObjTwo.style.left = leftValTwo - leftOne +'px';
}
else
{
colHeader.style.backgroundImage = document.defaultView.getComputedStyle(colHeader.parentNode, null).backgroundImage;
colHeader.style.width = colHeader.parentNode.clientWidth+'px';
colHeader.style.position = "absolute";
}
}
if (oBtn.attachEvent) //IE 中
{
oBtn.attachEvent('onscroll', function ()
{
var scrolltop = document.getElementById('Document').scrollTop;
//上边第一行
for(i=0;i<_FixedColHeaders.length;i++)
{
if(scrolltop<25)
{
document.getElementById(_FixedColHeaders[i]).style.top = "0px";
}
else
{
document.getElementById(_FixedColHeaders[i]).style.top = scrolltop+"px";
}
}
//后边的动态列
for(i=0;i<_DynamicColHeaders.length;i++)
{
var _colHeader=document.getElementById(_DynamicColHeaders[i]);
if(_colHeader==undefined) continue;
if(_colHeader==null) continue;
if(scrolltop<25)
{
document.getElementById(_DynamicColHeaders[i]).style.top = "0px";
}
else
{
document.getElementById(_DynamicColHeaders[i]).style.top = scrolltop+"px";
}
}
});
}
else //firefox googleChorme
{
oBtn.addEventListener('scroll', function ()
{
var scrolltop = document.getElementById('Document').scrollTop;
//_FixedColHeaders = ['1','2','3','4','5'];
//左边前六列
for(i=0;i<_FixedColHeaders.length;i++)
{
//console.log('t=====',document.getElementById(_FixedColHeaders[i]))
document.getElementById(_FixedColHeaders[i]).style.position = "absolute";
if(scrolltop<25)
{
document.getElementById(_FixedColHeaders[i]).style.top = "0px";
}
else
{
document.getElementById(_FixedColHeaders[i]).style.top = scrolltop+"px";
}
}
//后边的动态列
for(i=0;i<_DynamicColHeaders.length;i++)
{
var _colHeader=document.getElementById(_DynamicColHeaders[i]);
if(_colHeader==undefined) continue;
if(_colHeader==null) continue;
document.getElementById(_DynamicColHeaders[i]).style.position = "absolute";
if(scrolltop<25)
{
document.getElementById(_DynamicColHeaders[i]).style.top = "0px";
}
else
{
document.getElementById(_DynamicColHeaders[i]).style.top = scrolltop+"px";
}
}
}, false);
}
}
</script>
ps:上面代码写个比较粗糙,需要进一步整理。
lockheader()函数?完全可以不用函数吧,代码可以直接执行
全局函数中,有如下内容
结表头的实现4:交叉列表的表头冻结---多层交叉表
这种情况,把表头区分为固定区,固定区,固定区表头按固定区的方式处理
动态区表头,需要分行处理
内容固定的表头,处理方式同前。
交叉表头,首先要给交叉表头动态赋予id,方便后边识别
不多说直接上图与代码:
(第一层表头绑定)
(第2层表头绑定id)
代码部分:
function lockHeader(){
//固定行 最好改为二维数组?
_fixedCells = ['c','d','g','h'];
//上边第一列
_cells_inRow1 = ['1','2','3'];
//上边第二列
cellTwo = ['1','2','3','4','5','6','7'];
_cells_inRow2 = new Array();
//构造左边第二列的id
var a = 0;
//构造上边第二列的id
a=0;
for(i=0;i<_cells_inRow1.length;i++){
for(j=0;j<cellTwo.length;j++){
_cells_inRow2[a] = _cells_inRow1[i]+cellTwo[j];
a++;
}
}
//固定行的样式
for(i=0;i<_fixedCells.length;i++){
if(i<2){ //fixed cell in row1
document.getElementById(_fixedCells[i]).style.lineHeight = '28px';
document.getElementById(_fixedCells[i]).style.top = '0px';
document.getElementById(_fixedCells[i]).style.width = document.getElementById(_fixedCells[i]).parentNode.clientWidth+'px'; //th
var _doc = document.getElementById('Document');
if(_doc.attachEvent){ //区别浏览器 ie
document.getElementById(_fixedCells[i]).style.backgroundImage = document.getElementById(_fixedCells[i]).parentNode.currentStyle.backgroundImage;
document.getElementById(_fixedCells[i]).style.position = "absolute";
//document.getElementById(_fixedCells[i]).style.background = '#E3E9F1';
var cellObj = document.getElementById(_fixedCells[i]);
//为什么要加修正值
//var leftVal=cellObj.offsetLeft-offsetLeftMoveVal2;
//var leftVal=cellObj.offsetLeft;
//cellObj.style.left = leftVal+'px';
//取得父元素左边
//cellObj.style.left =cellObj.parentNode.style.left+"px";
//console.log(cellObj.parentNode.offsetLeft);
//console.log(cellObj.offsetLeft);
cellObj.style.left=cellObj.parentNode.offsetLeft+"px"
}else{ //chromel
document.getElementById(_fixedCells[i]).style.backgroundImage = document.defaultView.getComputedStyle
(document.getElementById(_fixedCells[i]).parentNode, null).backgroundImage;
document.getElementById(_fixedCells[i]).style.position = "absolute";
}
}else{ //row2
document.getElementById(_fixedCells[i]).style.lineHeight = '28px';
document.getElementById(_fixedCells[i]).style.top = '28px';
document.getElementById(_fixedCells[i]).style.width = document.getElementById(_fixedCells[i]).parentNode.clientWidth+'px';
if(_doc.attachEvent){ //ie
document.getElementById(_fixedCells[i]).style.backgroundImage = document.getElementById(_fixedCells[i]).parentNode.currentStyle.backgroundImage;
document.getElementById(_fixedCells[i]).style.position = "absolute";
//document.getElementById(_fixedCells[i]).style.background = '#E3E9F1';
var cellObj = document.getElementById(_fixedCells[i]);
//var leftVal=cellObj.offsetLeft-offsetLeftMoveVal2;
//var leftVal=cellObj.offsetLeft;
//cellObj.style.left = leftVal+'px';
//取得父元素左边
//cellObj.style.left =cellObj.parentNode.style.left+"px";
//console.log(cellObj.parentNode.offsetLeft);
//console.log(cellObj.offsetLeft);
cellObj.style.left=cellObj.parentNode.offsetLeft+"px"
}else{
document.getElementById(_fixedCells[i]).style.backgroundImage = document.defaultView.getComputedStyle
(document.getElementById(_fixedCells[i]).parentNode, null).backgroundImage;
document.getElementById(_fixedCells[i]).style.position = "absolute";
}
}
}
//上边第一行(动态部分)的样式
for(i=0;i<_cells_inRow1.length;i++){
document.getElementById(_cells_inRow1[i]).style.lineHeight = '28px';
document.getElementById(_cells_inRow1[i]).style.top = '0px';
document.getElementById(_cells_inRow1[i]).style.width = document.getElementById(_cells_inRow1[i]).parentNode.clientWidth
+'px';
if(_doc.attachEvent){ //ie
document.getElementById(_cells_inRow1[i]).style.backgroundImage = document.getElementById(_cells_inRow1[i]).parentNode.currentStyle.backgroundImage;
document.getElementById(_cells_inRow1[i]).style.position = "absolute";
var cellOneObj= document.getElementById(_cells_inRow1[i]);
cellOneObj.style.left=cellOneObj.parentNode.offsetLeft+"px"
}else{ //chrome
document.getElementById(_cells_inRow1[i]).style.backgroundImage = document.defaultView.getComputedStyle(document.getElementById(_cells_inRow1[i]).parentNode, null).backgroundImage;
document.getElementById(_cells_inRow1[i]).style.position = "absolute";
}
}
//上边第二行的样式
for(i=0;i<_cells_inRow2.length;i++){
if(document.getElementById(_cells_inRow2[i])){
document.getElementById(_cells_inRow2[i]).style.lineHeight = '28px';
document.getElementById(_cells_inRow2[i]).style.top = '28px';
document.getElementById(_cells_inRow2[i]).style.width = document.getElementById(_cells_inRow2
[i]).parentNode.clientWidth+'px';
if(_doc.attachEvent){ //IE
document.getElementById(_cells_inRow2[i]).style.backgroundImage = document.getElementById(_cells_inRow2[i]).parentNode.currentStyle.backgroundImage;
document.getElementById(_cells_inRow2[i]).style.position = "absolute";
var cellTwoObj = document.getElementById(_cells_inRow2[i]);
cellTwoObj.style.left=cellTwoObj.parentNode.offsetLeft+"px"
}else{
document.getElementById(_cells_inRow2[i]).style.backgroundImage = document.defaultView.getComputedStyle(document.getElementById(_cells_inRow2[i]).parentNode, null).backgroundImage;
document.getElementById(_cells_inRow2[i]).style.position = "absolute";
}
}
}
var _doc = document.getElementById('Document');
if (_doc.attachEvent){ //IE 中
_doc.attachEvent('onscroll',function(){
var scrolltop = document.getElementById('Document').scrollTop;
//固定行样式
for(i=0;i<_fixedCells.length;i++){
if(i<2){ //first row
document.getElementById(_fixedCells[i]).style.top = scrolltop+"px";
}else{
if(scrolltop<29){
document.getElementById(_fixedCells[i]).style.top = 28+"px";
}else{
document.getElementById(_fixedCells[i]).style.top = 28+scrolltop+"px";
}
}
}
//上边第一行
for(i=0;i<_cells_inRow1.length;i++){
document.getElementById(_cells_inRow1[i]).style.top = scrolltop+"px";
}
//动态列头 上边第二行
for(i=0;i<_cells_inRow2.length;i++){
if(document.getElementById(_cells_inRow2[i])){
if(scrolltop<29){
document.getElementById(_cells_inRow2[i]).style.top = 28+"px";
}else{
document.getElementById(_cells_inRow2[i]).style.top = 28+scrolltop+"px";
}
}
}
});
}else {//firefox googleChorme
_doc.addEventListener('scroll', function () {
var scrolltop = document.getElementById('Document').scrollTop;
//固定行样式
for(i=0;i<_fixedCells.length;i++){
if(i<2){
document.getElementById(_fixedCells[i]).style.top = scrolltop+"px";
}else{
if(scrolltop<29){
document.getElementById(_fixedCells[i]).style.top = 28+"px";
}else{
document.getElementById(_fixedCells[i]).style.top = 28+scrolltop+"px";
}
}
}
//上边第一行
for(i=0;i<_cells_inRow1.length;i++){
document.getElementById(_cells_inRow1[i]).style.top = scrolltop+"px";
}
//上边第二行
for(i=0;i<_cells_inRow2.length;i++){
if(document.getElementById(_cells_inRow2[i])){
if(scrolltop<29){
document.getElementById(_cells_inRow2[i]).style.top = 28+"px";
}else{
document.getElementById(_cells_inRow2[i]).style.top = 28+scrolltop+"px";
}
}
}
}, false);
}
}
ie兼容性处理:
ie下,设置position属性,设置top,发现left 有偏移现象,必须设置left
这里采取取得父元素offsetleft方式,给当前元素赋予left属性,注意,offsetleft没有单位,left属性要单位。
ps:网上查到另外一个方案 没有试:
后面有机会测试一遍;
birt报表合并以及表头锁定功能的实现
其他:
birt报表 交叉报表相关表达式的理解:例如:data["NUM_Group3/BILLNAME_ODR/ODR"]
“_”可以理解为交叉,group3/billname、odr/odr 可以看成维度成员。