我在项目实际应用中,用javascript基于XML创建动态树,并实现跨浏览器的功能。但在实现时,通过nodes.length动态创建节点时,google的Chrome和FireFox都会出现死循环,实现不了预期目的,而IE却能实现预期目的。
原因是IE的XMLDOM的节点长度记录的是初始长度,而Chrome、FireFox的节点长度是动态变化的.
for(var i=0;i<pnlist.length;i++){//仅IE适用,其值是初始长度。
//通过这种方式实现动态变化,除了IE外,另外2浏览器会死循环,达不到预期目的!!
//for(var i=0;i<len;i++){ //IE、FireFox、Chrome通用;可以达到预期目的
//动态更新xml内容……
}
我写了一个测试页面,详细内容如下(js代码没有单独创建,有兴趣的朋友可以继续往下看……):
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE> New Document </TITLE>
<META NAME="Generator" CONTENT="EditPlus">
<META NAME="Author" CONTENT="">
<META NAME="Keywords" CONTENT="">
<META NAME="Description" CONTENT="">
<SCRIPT LANGUAGE="JavaScript">
<!--
var xmlDoc = null ;
var isIE = (navigator.appName=="Microsoft Internet Explorer") ;
//1、
function createDOM(){
//var isIE = (navigator.appName=="Microsoft Internet Explorer") ;
if(!isIE){
if(this.ns==null)this.ns="";if(this.root==null)this.root="";
return document.implementation.createDocument(this.ns,this.root,null);
}else {
var aVers = ["MSXML2.DOMDocument.5.0","MSXML2.DOMDocument.4.0","MSXML2.DOMDocument.3.0","MSXML2.DOMDocument","Microsoft.XmlDom"];
for(var i=0;i<aVers.length;i++){
try{
var oxmlDom = new ActiveXObject(aVers[i]);
return oxmlDom;
}catch(oError){
//不做任何处理
}
}
}
throw new Error("MSXML or 其他XMLDom对象没有安装!");
}
//2、//从规范的xml字符串生成xml对象
function createXMLDoc(xmlStr){
var xmldoc = null ;
if(isIE){
xmldoc = this.createDOM() ;
xmldoc.async="false";
xmldoc.loadXML(xmlStr);
}else {
var parser=new DOMParser();
xmldoc=parser.parseFromString(xmlStr,"text/xml");
}
//alert(xmldoc.documentElement.firstChild.nodeName);
return xmldoc ;
}
function reloadXML(xmldoc){
this.genXmlDTree(xmldoc);
}
function iniLoad(){
var strxml = "<xtree>"+
"<node>"+
"<id>x01</id>"+
"<pid>0</pid> "+
"<name>Killer-01.</name> "+
"<url>xxx/page.jsp?xx=yy</url> "+
"<title>标题1</title> "+
"<target>workSpace</target>"+
"<node>"+
"<id>x01d1</id>"+
"<pid>x01</pid> "+
"<name>Killer-01-01</name> "+
"<url>xxx/page.jsp</url> "+
"<title>标题011</title> "+
"<target>workSpace</target>"+
"</node>"+
"</node>"+
"<node id=/"second/">"+
"<id>x02</id>"+
"<pid>0</pid> "+
"<name>节点-02</name> "+
"<url>xxx/page.jsp</url> "+
"<title>标题====02</title> "+
"<target>workSpace</target>"+
"</node> "+
"</xtree>";
xmlDoc = createXMLDoc(strxml);
var oRoot = xmlDoc.documentElement ;
var str = null ;
if(isIE){
str = oRoot.xml;
}else{
alert("非IE浏览器:");
str =(new XMLSerializer()).serializeToString(oRoot);
}
document.getElementById("initData").value = "" ;
document.getElementById("dynData").value="";
document.getElementById("initData").value = str ;
}
function reloadMyData(){
var pnlist = xmlDoc.getElementsByTagName("node");//获得node节点 3个node
var len = pnlist.length ;
var ids = new Array() ;
for(var i=0;i<len;i++){
ids[i]=pnlist[i].getElementsByTagName("id")[0].childNodes[0].nodeValue;
}
//注意:关于xml节点长度问题
//pnlist.length 针对IE,其值是初始长度;针对FireFox、Chrome是动态长度
//
for(var i=0;i<pnlist.length;i++){//仅IE适用,其值是初始长度。
//通过这种方式实现动态变化,除了IE外,另外2浏览器会死循环,达不到预期目的!!
//for(var i=0;i<len;i++){ //IE、FireFox、Chrome通用;可以达到预期目的
var pn = pnlist[i];
alert("NODE长度:"+pnlist.length);
//var pid=ids[i];
var pid=pn.getElementsByTagName("id")[0].childNodes[0].nodeValue;
for(var m=0;m<2;m++){//每个node下再增加2个node节点
var nn =xmlDoc.createElement("node");
var cn=xmlDoc.createElement("id");
var txt=xmlDoc.createTextNode("cnid_"+i+"_"+m);
cn.appendChild(txt);
nn.appendChild(cn);
cn=xmlDoc.createElement("pid");
txt=xmlDoc.createTextNode(pid);
cn.appendChild(txt);
nn.appendChild(cn);
cn=xmlDoc.createElement("name");
txt=xmlDoc.createTextNode("Name_"+i+"_"+m);
cn.appendChild(txt);
nn.appendChild(cn);
cn=xmlDoc.createElement("url");
txt=xmlDoc.createTextNode("url/"+i+"_"+m+".jsp");
cn.appendChild(txt);
nn.appendChild(cn);
cn=xmlDoc.createElement("title");
txt=xmlDoc.createTextNode("title-tip-"+i+"_"+m);
cn.appendChild(txt);
nn.appendChild(cn);
cn=xmlDoc.createElement("target");
txt=xmlDoc.createTextNode("workSpace");
cn.appendChild(txt);
nn.appendChild(cn);
pn.appendChild(nn);
}
}
var oRoot = xmlDoc.documentElement ;
var str = null ;
if(isIE){
str = oRoot.xml;
}else{
alert("非IE浏览器:");
str =(new XMLSerializer()).serializeToString(oRoot);
}
document.getElementById("dynData").value = str ;
}
//-->
</SCRIPT>
</HEAD>
<BODY οnlοad="iniLoad()">
初始化xml:<BR>
<TEXTAREA id="initData" style="background-color:#9999FF" NAME="" ROWS="20" COLS="120"></TEXTAREA>
<HR>
动态加载xml:<INPUT TYPE="button" NAME="" value="动态加载" οnclick="reloadMyData()"><BR>
<TEXTAREA id="dynData" style="background-color:#9999FF" NAME="" ROWS="20" COLS="120"></TEXTAREA>
</BODY>
</HTML>