jQuery实现冻结表格行和列
客户要求实现对表格数据的头几行或者头几列进行冻结,即滚动时保持这几行/列不动,通过网上查找代码,参考已有的代码的思路,实现了可以任意对行、列进行冻结。
实现原理:
创建多个div,div之间通过css实现层叠,每个div放置当前表格的克隆。例如:需要行冻结时,创建存放冻结行表格的div,通过设置z-index属性和position属性,让冻结行表格在数据表格的上层。同理,需要列冻结时,创建存放冻结列表格的div,并放置在数据表格的上层。如果需要行列都冻结时,则除了创建冻结行、冻结列表格的div,还需要创建左上角的固定行列表格的div,并放置在所有div的最上层。
处理表格的滚动事件,在表格横向或者纵向滚动时,同时让相应的冻结行和冻结列也同步滚动。
处理html的resize事件,同步修改表格的滚动区域宽度和高度
代码如下:
/*
*锁定表头和列
*
*参数定义
*table-要锁定的表格元素或者表格ID
*freezeRowNum-要锁定的前几行行数,如果行不锁定,则设置为0
*freezeColumnNum-要锁定的前几列列数,如果列不锁定,则设置为0
*width-表格的滚动区域宽度
*height-表格的滚动区域高度
*/
functionfreezeTable(table,freezeRowNum,freezeColumnNum,width,height){
if(typeof(freezeRowNum)=='string')
freezeRowNum=parseInt(freezeRowNum)
if(typeof(freezeColumnNum)=='string')
freezeColumnNum=parseInt(freezeColumnNum)
vartableId;
if(typeof(table)=='string'){
tableId=table;
table=$('#'+tableId);
}else
tableId=table.attr('id');
vardivTableLayout=$("#"+tableId+"_tableLayout");
if(divTableLayout.length!=0){
divTableLayout.before(table);
divTableLayout.empty();
}else{
table.after("<divid='"+tableId+"_tableLayout'style='overflow:hidden;height:"+height+"px;width:"+width+"px;'></div>");
divTableLayout=$("#"+tableId+"_tableLayout");
}
varhtml='';
if(freezeRowNum>0&&freezeColumnNum>0)
html+='<divid="'+tableId+'_tableFix"style="padding:0px;"></div>';
if(freezeRowNum>0)
html+='<divid="'+tableId+'_tableHead"style="padding:0px;"></div>';
if(freezeColumnNum>0)
html+='<divid="'+tableId+'_tableColumn"style="padding:0px;"></div>';
html+='<divid="'+tableId+'_tableData"style="padding:0px;"></div>';
$(html).appendTo("#"+tableId+"_tableLayout");
vardivTableFix=freezeRowNum>0&&freezeColumnNum>0?$("#"+tableId+"_tableFix"):null;
vardivTableHead=freezeRowNum>0?$("#"+tableId+"_tableHead"):null;
vardivTableColumn=freezeColumnNum>0?$("#"+tableId+"_tableColumn"):null;
vardivTableData=$("#"+tableId+"_tableData");
divTableData.append(table);
if(divTableFix!=null){
vartableFixClone=table.clone(true);
tableFixClone.attr("id",tableId+"_tableFixClone");
divTableFix.append(tableFixClone);
}
if(divTableHead!=null){
vartableHeadClone=table.clone(true);
tableHeadClone.attr("id",tableId+"_tableHeadClone");
divTableHead.append(tableHeadClone);
}
if(divTableColumn!=null){
vartableColumnClone=table.clone(true);
tableColumnClone.attr("id",tableId+"_tableColumnClone");
divTableColumn.append(tableColumnClone);
}
$("#"+tableId+"_tableLayouttable").css("margin","0");
if(freezeRowNum>0){
varHeadHeight=0;
varignoreRowNum=0;
$("#"+tableId+"_tableHeadtr:lt("+freezeRowNum+")").each(function(){
if(ignoreRowNum>0)
ignoreRowNum--;
else{
vartd=$(this).find('td:first,th:first');
HeadHeight+=td.outerHeight(true);
ignoreRowNum=td.attr('rowSpan');
if(typeof(ignoreRowNum)=='undefined')
ignoreRowNum=0;
else
ignoreRowNum=parseInt(ignoreRowNum)-1;
}
});
HeadHeight+=2;
divTableHead.css("height",HeadHeight);
divTableFix!=null&&divTableFix.css("height",HeadHeight);
}
if(freezeColumnNum>0){
varColumnsWidth=0;
varColumnsNumber=0;
$("#"+tableId+"_tableColumntr:eq("+freezeRowNum+")").find("td:lt("+freezeColumnNum+"),th:lt("+freezeColumnNum+")").each(function(){
if(ColumnsNumber>=freezeColumnNum)
return;
ColumnsWidth+=$(this).outerWidth(true);
ColumnsNumber+=$(this).attr('colSpan')?parseInt($(this).attr('colSpan')):1;
});
ColumnsWidth+=2;
divTableColumn.css("width",ColumnsWidth);
divTableFix!=null&&divTableFix.css("width",ColumnsWidth);
}
divTableData.scroll(function(){
divTableHead!=null&&divTableHead.scrollLeft(divTableData.scrollLeft());
divTableColumn!=null&&divTableColumn.scrollTop(divTableData.scrollTop());
});
divTableFix!=null&&divTableFix.css({"overflow":"hidden","position":"absolute","z-index":"50"});
divTableHead!=null&&divTableHead.css({"overflow":"hidden","width":width-17,"position":"absolute","z-index":"45"});
divTableColumn!=null&&divTableColumn.css({"overflow":"hidden","height":height-17,"position":"absolute","z-index":"40"});
divTableData.css({"overflow":"scroll","width":width,"height":height,"position":"absolute"});
divTableFix!=null&&divTableFix.offset(divTableLayout.offset());
divTableHead!=null&&divTableHead.offset(divTableLayout.offset());
divTableColumn!=null&&divTableColumn.offset(divTableLayout.offset());
divTableData.offset(divTableLayout.offset());
}
/*
*调整锁定表的宽度和高度,这个函数在resize事件中调用
*
*参数定义
*table-要锁定的表格元素或者表格ID
*width-表格的滚动区域宽度
*height-表格的滚动区域高度
*/
functionadjustTableSize(table,width,height){
vartableId;
if(typeof(table)=='string')
tableId=table;
else
tableId=table.attr('id');
$("#"+tableId+"_tableLayout").width(width).height(height);
$("#"+tableId+"_tableHead").width(width-17);
$("#"+tableId+"_tableColumn").height(height-17);
$("#"+tableId+"_tableData").width(width).height(height);
}
functionpageHeight(){
if($.browser.msie){
returndocument.compatMode=="CSS1Compat"?document.documentElement.clientHeight:document.body.clientHeight;
}else{
returnself.innerHeight;
}
};
//返回当前页面宽度
functionpageWidth(){
if($.browser.msie){
returndocument.compatMode=="CSS1Compat"?document.documentElement.clientWidth:document.body.clientWidth;
}else{
returnself.innerWidth;
}
};
$(document).ready(function(){
vartable=$("table");
vartableId=table.attr('id');
varfreezeRowNum=table.attr('freezeRowNum');
varfreezeColumnNum=table.attr('freezeColumnNum');
if(typeof(freezeRowNum)!='undefined'||typeof(freezeColumnNum)!='undefined'){
freezeTable(table,freezeRowNum||0,freezeColumnNum||0,pageWidth(),pageHeight());
varflag=false;
$(window).resize(function(){
if(flag)
return;
setTimeout(function(){
adjustTableSize(tableId,pageWidth(),pageHeight());
flag=false;
},100);
flag=true;
});
}
});
使用时,只要在table元素设置freezeRowNum和freezeColumnNum属性值,即可实现冻结效果
<tableid="reportTable"width="1900"freezeRowNum="2"freezeColumnNum="2"class="report"align="center"> ... </table>
以上所述就是本文的全部内容了,希望大家能够喜欢。