瀏覽器中XML DOM的支援IE中通過ActiveXObject實現了XML的支援,存在一下幾個版本:Microsoft.XmlDom,MSXML2.DOMDocument,MSXML2.DOMDocument.3.0,MSXML2.DOMDocument.4.0,MXXML2.DOMDocument.5.0 IE678使用ActiveXObject來實現XML支援,可以通過loadXML()來傳入XML字串;在現代瀏覽器下通過document.implementation.createDocument來實現XML支援,還原序列化需要通過DOMParse對象以及parseFromString方法來完成。 對於載入文檔完成後的事件觸發,IE678使用的是onreadystatechange事件以及判斷readyState屬性來得知狀態;對於現代瀏覽器使用的是onload事件。 對於一個XML對象,IE678提供了xml屬性序列化;對於現代瀏覽器,需要(new XMLSerializer).serializeToString來序列化。 如上分析,想要實現相容,可以通過document.prototype.loadXML來實現現代瀏覽器的loadXML相容;可以通過ES5的Object.defineProperty來定義現代瀏覽器的readyState屬性,在set為4的時候觸發onreadystatechange事件;可以通過ES5的Object.defineProperty來定義現代瀏覽器的xml屬性,讀取的時候通過XMLSerializer對象來序列化。 不考慮異常和錯誤,測試代碼如下: 複製代碼 1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 5 <style rel="stylesheet" type="text/css"> 6 </style> 7 <script type="text/javascript"> 8 function createXMLDOM() { 9 if(!createXMLDOM.cache){ 10 // 現代瀏覽器分支. 11 if(document.implementation && document.implementation.createDocument){ 12 createXMLDOM.cache=function(){ 13 var xmldom=document.implementation.createDocument("","",null); 14 15 // 相容onreadystatechange方法. 16 _fix_onreadystatechange.call(xmldom); 17 // 添加一個觸發事件. 18 xmldom.addEventListener("load",function(){ 19 // 設定readyState為4.被動觸發onreadystatechange事件. 20 this.readyState=4; 21 },false); 22 return xmldom; 23 }; 24 // 相容loadXML方法. 25 _fix_loadXML(); 26 // 相容xml屬性 27 _fix_xml(); 28 return createXMLDOM.cache(); 29 } 30 // IE678分支. 31 else if(window.ActiveXObject){ 32 var vs=["MSXML2.DOMDocument.5.0","MSXML2.DOMDocument.4.0", 33 "MSXML2.DOMDocument.3.0","MSXML2.DOMDocument", 34 "Microsoft.XmlDom"]; 35 for(var i=0,j=vs.length;i<j;i++){ 36 try{ 37 var oxmldom=new ActiveXObject(vs[i]); 38 createXMLDOM.cache=new Function("x","return new ActiveXObject('"+vs[i]+"');"); 39 40 return oxmldom; 41 } 42 catch(ex){} 43 } 44 } 45 // 都不相容. 46 else{ 47 createXMLDOM.cache=new Function("return null;"); 48 return null; 49 } 50 } 51 else{ 52 return createXMLDOM.cache(); 53 } 54 } 55 56 /* loadXML的相容處理.現代瀏覽器. */ 57 function _fix_loadXML(){ 58 Document.prototype.loadXML=function(sxml){ 59 var oparse=new DOMParser(); 60 var oxmldom=oparse.parseFromString(sxml, "text/xml"); 61 while(this.firstChild){ 62 this.removeChild(this.firstChild); 63 } 64 for(var i=0,j=oxmldom.childNodes.length;i<j;i++){ 65 // 擷取另一個文檔的某個節點以及所有子節點. 66 var onewnode=this.importNode(oxmldom.childNodes[i],true); 67 // 添加到該文檔中. 68 this.appendChild(onewnode); 69 } 70 // 這裡修正readyState屬性. 71 this.readyState=4; 72 }; 73 } 74 /* 處理onreadystatechange的相容. */ 75 function _fix_onreadystatechange(){ 76 if(Object.defineProperty){ 77 Object.defineProperty(this,"readyState",{ 78 get:function(){ 79 return this.__readyState__; 80 }, 81 set:function(i){ 82 this.__readyState__=i; 83 this.onreadystatechange(); 84 } 85 }); 86 } 87 } 88 /* 現代瀏覽器需要通過DOMParser對象並通過parseFromString來轉換XML文檔為字串 */ 89 function _fix_xml(){ 90 // ES5新特性. 91 if(Object.defineProperty){ 92 Object.defineProperty(Node.prototype,"xml",{ 93 get:function(){ 94 return (new XMLSerializer).serializeToString(this,"text/xml"); 95 } 96 }) 97 } 98 // 如下分支IE9開始不支援了.非W3C標準. 99 //else if(Node.prototype.__defineGetter__){100 // Node.prototype.__defineGetter__("xml",function(){101 // return (new XMLSerializer).serializeToString(this,"text/xml");102 // });103 //}104 }105 106 /* 測試 */107 window.onload=function(){108 var xml1=createXMLDOM();109 var xml2=createXMLDOM();110 xml2.onreadystatechange=function(){111 // 這裡不能用this.因為在處理ActiveX對象可能出現問題.112 if(xml2.readyState==4){113 document.body.innerHTML+="load xml ok<br/>";114 }115 }116 xml2.loadXML("<xml><blog>xf_z1988</blog></xml>");117 var xml_str=xml2.xml.replace(/</g,"<").replace(/>/g,">");118 document.body.innerHTML+=xml_str;119 };120 </script>121 </head>122 <body></body>123 </html>複製代碼