Javascript在IE下有一个隐藏的函数CollectGarbage();和JAVA语言类似,将引用设置成null,并不会释放内存,需要手动调用CollectGarbage();才会对内存进行释放.
正是这个函数解决了Table2Tree的内存问题.
Table2Tree的源代码修正如下
/**
Javascript标准库:Table转换成树形Table
前置条件:需要包含prototype.js文件
调用函数table2tree即可生成树形表格
函数调用协议:void table2tree(config)
参数config是一个类,其中属性有
tableName :表格的名称,HTML代码中id指定
rootId :树形的根ID,业务代码,例如0标识省分
treeId :TR上面的标识树节点当前ID的属性,默认为treeId
treeParentId :TR上面标识树节点的父亲ID的属性,默认为treeParentId
imageRoot :使用的图片所在的目录,目录中的图片命名有强制约定,
empty.gif空,folder.gif目录关闭状态folderopen.gif目录打开状态
checkMode :是否使用JS生成checkBox,默认为-1。
值0:只生成页节点的checkBox,
值1:生成页节点和目录节点的CheckBox,但是不联动选择,
值2:生成页节点和目录节点的CheckBox,联动选择。
showLine :是否显示树形的前面的线条,默认为false
columnIndex :树形显示在表格中的第几列,从0开始,默认为0,
如果输入的数据大于表格最大列数,自动设置为0.
checkBoxFormator :格式化checkbox的字符串,例如"checked onclick='alert(\"#TREEID#\")'"
表示在checkbox初始化的时候自动选中,并且赋予checkbox的onclick函数,脚本中可以使用特殊的标识
#TREEID#:树形节点的当前ID
#TREEPARENTID#:节点的父亲ID
#TR.属性名称#:当前行的TR的属性。
#TD.属性名称#:树形所在的TD的属性
注意,此处使用的是字符串直接替换
collapseOnLabel :是否开启在目录节点上点击文本信息自动对树进行展开和关闭的功能。
checkOnLabel :是否开启点击页节点上的文本信息自动进行checkBox选择的功能
expandLevel :展开的层次深度
调用实例:
window.Table2Tree.create({tableName:"TestTableTree",rootId:"0",treeId:"xid",treeParentId:"pid"});
**/
if(null==window.Table2Tree)
{
window.Table2Tree={};
window.Table2Tree.create=function(config)
{
if(null==config||null==config.tableName||null==config.rootId)
{
alert("JavaScript:table2Tree 函数调用错误");
return;
}
var table=$(config.tableName);
if(null==table)
{
return;
}
var expandLevel =config.expandLevel==null?-1:config.expandLevel;
var strImageRoot=config.imageRoot==null?"images/tree/":config.imageRoot+"/";
var strRootKeyID=config.rootId==null?"":config.rootId;
table.treeparameter_imageRoot=strImageRoot;
var treePName=config.treeId==null?"treeId":config.treeId;
var treeParentPName=config.treeParentId==null?"treeParentId":config.treeParentId;
var checkMode=config.checkMode==null?-1:config.checkMode;
var isShowLine=config.showLine==null?false:config.showLine;
var nColumnIndexId=config.columnIndex==null?0:config.columnIndex;
var checkBoxFomator=config.checkBoxFormator;
var collapseOnLabel=config.collapseOnLabel==null?false:config.collapseOnLabel;
var checkOnLabel=config.checkOnLabel==null?true:config.checkOnLabel;
window.Table2Tree._maketreeNode(table,treePName,treeParentPName,
table.tBodies[0].rows,nColumnIndexId,
strRootKeyID,isShowLine,collapseOnLabel,checkMode,checkBoxFomator,checkOnLabel,expandLevel);
table.treeparameter_colIndex=nColumnIndexId;
table.treeparameter_pName=treePName;
table.treeparameter_pParentName=treeParentPName;
}
window.Table2Tree.collapse=function(imgEvent)
{
if(null==imgEvent)
{
imgEvent=null==event?null:event.srcElement;
}
if(null==imgEvent)
{
return;
}
var table=findParentByTagName(imgEvent,"table");
var row=findParentByTagName(imgEvent,"tr");
if(row==null||null==table)
{
return;
}
var img1=null;
var img2=null;
for(var x=0;x<imgEvent.parentNode.children.length;x++)
{
if(imgEvent.parentNode.children[x].tagName.toLowerCase()=="img" &&
imgEvent.parentNode.children[x].itr!=null)
{
if(img1==null){img1=imgEvent.parentNode.children[x];}
else {img2=imgEvent.parentNode.children[x];}
}
}
var treeIdPName=table.treeparameter_pName;
var treeParentIdPName=table.treeparameter_pParentName;
var allNodes=table.tBodies[0].rows;
var ary=window.Table2Tree._subNodes(allNodes,treeIdPName,treeParentIdPName,row[treeIdPName]);
var b=row.treeparameter_toggle==null||row.treeparameter_toggle==1?false:true;
//alert("row.treeparameter_toggle "+row.treeparameter_toggle+"+"+b);
row.treeparameter_toggle=row.treeparameter_toggle==null||row.treeparameter_toggle==1?0:1;
var srcImageRoot=table.treeparameter_imageRoot;
//if(null!=img1){img1.src=srcImageRoot+(b==false?"plus.gif":"minus.gif");}
if(null!=img1){img1.src=b?img1.src.replace("plus","minus"):img1.src.replace("minus","plus");}
if(null!=img2){img2.src=srcImageRoot+(b==false?"folder.gif":"folderopen.gif");}
for(var n=0;n<ary.length;n++)
{
ary[n].style.display=b?"":"none";
window.Table2Tree._toggle(allNodes,treeIdPName,treeParentIdPName,ary[n],b);
}
}
window.Table2Tree.labelClicked=function(aId)
{
if(null==aId||null==aId.previousSibling||null==aId.previousSibling.checked)
{
return;
}
var ck=aId.previousSibling;
ck.checked=!ck.checked;
if(null!=ck.onclick)
{
ck.fireEvent("onclick");
}
}
window.Table2Tree.checkNode=function(spanI,hideMsgMask)
{
var checkBox=spanI;
if(spanI.tagName.toLowerCase()!="input")
{
var xAry=findChildrenByTagName(spanI,"input");
checkBox=xAry.length>0?xAry[0]:null;
}
if(null==checkBox)
{
checkBox=event.srcElement;
}
if(null==checkBox)
{
return;
}
var table=findParentByTagName(checkBox,"table");
var row=findParentByTagName(checkBox,"tr");
var td=findParentByTagName(checkBox,"td");
if(row==null||null==table)
{
return;
}
var treeIdPName=table.treeparameter_pName;
var treeParentIdPName=table.treeparameter_pParentName;
var treeValue=row[treeIdPName];
if(null==treeValue)
{
return;
}
var nColIndex=table.treeparameter_colIndex;
var allNodes=table.tBodies[0].rows;
var ary=window.Table2Tree._subNodes(allNodes,treeIdPName,treeParentIdPName,treeValue);
if(ary!=null && ary.length>0)
{
if(null==hideMsgMask &&
false==confirm("当前的节点包含下级的选择框,\r\n您需要设置所有下级选择框的选择状态和当前"+td.innerText+" 选择一致吗?"))
{
return;
}
for(var n=0;n<ary.length;n++)
{
var aryTds=ary[n].cells;
var td=nColIndex>=aryTds.length?aryTds[0]:aryTds[nColIndex];
var arys=findChildrenByTagName(td,"input");
for(var nc=0;nc<arys.length;nc++)
{
ck=arys[nc];
if(null!=ck.type && ck.type.toLowerCase()=="checkbox")
{
ck.checked=checkBox.checked;
window.Table2Tree.checkNode(ck,"1");
break;
}
}
}
}
}
window.Table2Tree._toggle=function(allNodes,treeIdPName,treeParentIdPName,row,b)
{
if(null==row)
{
return;
}
var ary=window.Table2Tree._subNodes(allNodes,treeIdPName,treeParentIdPName,row[treeIdPName]);
if(null==ary||ary.length<1)
{
return;
}
var bClosed=row.treeparameter_toggle==null||row.treeparameter_toggle==1?false:true;
if(bClosed==false)//上级打开,当前展开中则需要显示下级、上级关闭,当前展开中则需要隐藏下级
{
for(var n=0;n<ary.length;n++)
{
ary[n].style.display=b?"":"none";
window.Table2Tree._toggle(allNodes,treeIdPName,treeParentIdPName,ary[n],b);
}
}
}
window.Table2Tree._subNodesCache={};
window.Table2Tree._subNodes=function(ary,propId,propPId,parentValue)
{
if(null==parentValue||null==propId||null==propPId||propPId==propId)
{
return [];
}
if(window.Table2Tree._subNodesCache[parentValue]!=null)
{
return window.Table2Tree._subNodesCache[parentValue];
}
var ret=[];
for(var n=0;n<ary.length;n++)
{
var row=ary[n];
if((null==row[propPId] && null==row[propId])||row[propPId]!=parentValue||row.cells.length<1)
{
continue;
}
ret.push(row);
}
window.Table2Tree._subNodesCache[parentValue]=ret;
return ret;
}
window.Table2Tree._appendAll=function(a,ary)
{
if(null==a.childNodes)
{
return;
}
if(a.childNodes.length<1)
{
a.appendChild(document.createElement("font"));
}
var b=a.childNodes[0];
for(var n=0;n<ary.length;n++)
{
a.insertBefore(ary[n],b);
}
}
window.Table2Tree._maketreeNode=function(strTableName,treeIdPName,treeParentIdPName,aryRows,nColumnIndexId,
parentTreeIDValue,isAddTreeLine,collapseOnLabel,checkboxMode,checkBoxFormator,checkOnLabel,expandLevel,
treeDeep,lastNodeArray)
{
treeIdPName=null==treeIdPName?"treeId":treeIdPName;
treeParentIdPName=null==treeParentIdPName?"treeParentId":treeParentIdPName;
var table=$(strTableName);
if(null==table)
{
return;
}
nColumnIndexId=null==nColumnIndexId||nColumnIndexId<0?0:nColumnIndexId;
treeDeep=treeDeep==null?0:treeDeep;
lastNodeArray=null==lastNodeArray?[]:lastNodeArray;
var pidsubsAll=window.Table2Tree._subNodes(aryRows,treeIdPName,treeParentIdPName,parentTreeIDValue);
var srcImageRoot=table.treeparameter_imageRoot;
var pidsubs=[];
var pidsubs_Pages=[];
for(var nTreeNode=0;nTreeNode<pidsubsAll.length;nTreeNode++)
{
var row=pidsubsAll[nTreeNode];
if(window.Table2Tree._subNodes(aryRows,treeIdPName,treeParentIdPName,row[treeIdPName]).length<1)
{
pidsubs_Pages.push(row);
}
else
{
pidsubs.push(row);
}
}
var folderCount=pidsubs.length;
if(pidsubs_Pages.length>0)
{
pidsubs.pushArray(pidsubs_Pages);
}
for(var nTreeNode=0;nTreeNode<pidsubs.length;nTreeNode++)
{
var isLastTreeNode=(nTreeNode==pidsubs.length-1);//是否是最后一个
lastNodeArray[treeDeep]=isLastTreeNode;
var row=pidsubs[nTreeNode];
var aryTds=row.cells;
var td=nColumnIndexId<aryTds.length?aryTds[nColumnIndexId]:aryTds[0];
var bFolder=window.Table2Tree._subNodes(aryRows,treeIdPName,treeParentIdPName,row[treeIdPName]).length>0;
row.treeparameter_toggle=treeDeep>expandLevel-1?0:1;
var isExpand=row.treeparameter_toggle!=0;
if(treeDeep>0 &&treeDeep>expandLevel){row.style.display="none";}
table.childNodes[0].appendChild(row);
var bHavePage=aryTds[0].children.length>0&&null!=aryTds[0].children[0].tagName&&aryTds[0].children[0].tagName.toLowerCase()=="img";
var ary=[];
for(var x=0;x<treeDeep;x++)
{
if(isAddTreeLine)
{
if(!lastNodeArray[x])
{
ary.push(document.createElement("<img class='tree' align='absmiddle' src='"+srcImageRoot+"img-vert-line.gif'>"));
}
else
{
ary.push(document.createElement("<img class='tree' align='absmiddle' src='"+srcImageRoot+"empty.gif'>"));
}
if(x>=1)
{
ary.push(document.createElement("<img class='tree' align='absmiddle' src='"+srcImageRoot+"empty.gif'>"));
}
}
else
{
ary.push(document.createElement("<img class='tree' align='absmiddle' src='"+srcImageRoot+"empty.gif'>"));
}
}
if(isAddTreeLine)
{
var imgsrc=treeDeep>0?"<img class='tree' align='absmiddle' src='"+srcImageRoot+
(isAddTreeLine?(isLastTreeNode?"img-branch-end":"img-branch-cont"):"empty")+
".gif'>":null;
if(imgsrc)ary.push(document.createElement(imgsrc));
}
var checkBoxAppend="";
if(null!=checkBoxFormator && checkboxMode>=0)
{
checkBoxAppend=checkBoxFormator.replace("#TREEID#",row[treeIdPName])
.replace("#TREEPARENTID#",row[treeParentIdPName]);
for(var p in row)
{
if(row[p]==null||null==row[p].toString||
row[p].toString().length<1||
row[p].toString()=="[object]"||
row[p].toString().indexOf("<")>=0)
{
continue;
}
checkBoxAppend=checkBoxAppend.replace("#TR."+p.toUpperCase()+"#",row[p]);
}
for(var p in td)
{
if(td[p]==null||null==td[p].toString||
td[p].toString().length<1||
td[p].toString()=="[object]"||
td[p].toString().indexOf("<")>=0)
{
continue;
}
checkBoxAppend=checkBoxAppend.replace("#TD."+p.toUpperCase()+"#",td[p]);
}
}
if(bFolder)
{
var pImage="plus";
if(treeDeep==0 && isAddTreeLine)
{
if(isLastTreeNode)
{
pImage="img-plus-end";
}
else
{
pImage="img-plus-cont";
}
}
if(isExpand)
{
pImage=pImage.replace("plus","minus");
}
ary.push(document.createElement("<img onclick='window.Table2Tree.collapse(this)' class='tree' itr='1' align='absmiddle' src='"+srcImageRoot+pImage+".gif'>"));
if(bHavePage==false)
{
ary.push(document.createElement("<img onclick='window.Table2Tree.collapse(this)' class='tree' itr='1' align='absmiddle' src='"+srcImageRoot+
(isExpand?"folderopen":"folder")+".gif'>"));
}
if(null!=checkboxMode && checkboxMode>=1)
{
if(checkboxMode>1)
{
var span=document.createElement("<span onclick='window.Table2Tree.checkNode(this)'>")
.appendChild(document.createElement("<input type='checkbox' "+checkBoxAppend+"/>"));
ary.push(span);
}
else
{
ary.push(document.createElement("<input type='checkbox' "+checkBoxAppend+"/>"));
}
}
if(collapseOnLabel)
{
var span=document.createElement("<span onclick='window.Table2Tree.collapse(this)'>");
while(td.childNodes && td.childNodes.length>0)
{
span.appendChild(td.childNodes[0])
}
td.appendChild(span);
}
window.Table2Tree._appendAll(td,ary);
}
else//node.not a folder.
{
if(isAddTreeLine==false)ary.push(document.createElement("<img align='absmiddle' src='"+srcImageRoot+"empty.gif'>"));
if(bHavePage==false)
{
ary.push(document.createElement("<img align='absmiddle' src='"+srcImageRoot+"page.gif'>"));
}
if(null!=checkboxMode && checkboxMode>=0)
{
ary.push(document.createElement("<input type='checkbox' "+checkBoxAppend+" />"));
if(checkOnLabel)
{
var span=document.createElement("span");
span.onclick=function(){window.Table2Tree.labelClicked(this);};
while(td.childNodes && td.childNodes.length>0)
{
span.appendChild(td.childNodes[0])
}
td.appendChild(span);
}
}
window.Table2Tree._appendAll(td,ary);
}
//td.innerHTML+=isExpand;
td.style.border="solid 0px menu";
if(null==td.style.cursor||td.style.cursor=="")
{
td.style.cursor="hand";
}
ary=null;
CollectGarbage();
if(row[treeParentIdPName]!=row[treeIdPName])
{
window.Table2Tree._maketreeNode(strTableName,treeIdPName,treeParentIdPName,aryRows,nColumnIndexId,
row[treeIdPName],isAddTreeLine,collapseOnLabel,checkboxMode,checkBoxFormator,checkOnLabel,expandLevel,
treeDeep+1,lastNodeArray);
CollectGarbage();
}
}
pidsubs=null;
pidsubs_Pages=null;
pidsubsAll=null;
CollectGarbage();
}
}