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>
以上所述就是本文的全部内容了,希望大家能够喜欢。