天天看點

火狐不支援.xml 屬性 不支援.text屬性 不支援DSO資料島 火狐 firefox與ie不相容

最近在做浏覽器相容。對于不相容的方法就百度,還是比較耗時的,下面是我遇到的相容問題總結,希望能提高你的工作效率。

一、ie 支援  childNodes(i)  但 火狐隻支援 childNodes[i] 。需要批量替換,替換後火狐ie都支援。

二、ie對XMLDOM對象和DSO資料島有很好的支援,但火狐就不行了。後面遇到的相容性問題,解決辦法是:沒有對象,給它建立一個對象;沒有方法,給它添加一個方法;沒有屬性,給它增加一個屬性。能公用盡量公用。不然那麼多代碼一個一個改不現實。以下代碼都寫在公用js裡。應該能解決90%的相容性問題吧。如有疑問歡迎留言。

不支援的方法有:selectSingleNode() ,  selectNodes(), createElement(), attachEvent()

不支援的屬性有:documentElement,   xml ,  text 

//建立dom對象,建立後火狐沒有transformNode()方法,需要建立。

function createXMLDOM(str) {

        var xmlDom;

        if (!isIE()) {

            // 判斷正确 建立對象

            xmlDom = (new DOMParser()).parseFromString(str, 'text/xml');

            // 檢測是否xml文檔有沒有問題

            var error = xmlDom.getElementsByTagName("parsererror");

            debugger;

            if (error.length > 0) {

                throw new Error("XML格式有誤:" + str);

                //throw new Error("XML格式有誤:" + error[0].textContent);

            }

            //2020-4-16 

            //添加transformNode方法

            xmlDom.transformNode = function(oXslDom) {

                var oProcessor = new XSLTProcessor();

                oProcessor.importStylesheet(oXslDom);

                var oResultDom = oProcessor.transformToDocument(xmlDom);

                var oSerializer = new XMLSerializer();

                var sXml = oSerializer.serializeToString(oResultDom, "text/xml");

                return sXml;

            }

            //添加xml屬性  不能在此添加xml屬性,它不是動态的,dom發生變化,但xml沒有跟着變化。具體實作參見後面

            //var oSerializer = new XMLSerializer();

            //xmlObj = oSerializer.serializeToString(xmlDom);

            //xmlDom["xml"] = xmlObj;

            //判斷是否為 IE浏覽器

        }else{

            var arrSignatures = new Array("MSXML.DOMDocument", "MSXML2.DOMDocument", "MSXML2.DOMDocument.6.0", "MSXML2.DOMDocument.5.0", "MSXML2.DOMDocument.4.0", "MSXML2.DOMDocument.3.0", "Microsoft.XmlDom");

            for (var i = 0; i < arrSignatures.length; i++) {

                try {

                    xmlDom = new ActiveXObject(arrSignatures[i]);

                    if (arrSignatures[i] == "MSXML2.DOMDocument.6.0") {

                        xmlDom.setProperty("AllowXsltScript", "true");

                    }

                    break;

                }

                catch (ex) {

                }

            }

            xmlDom.async = false;

            xmlDom.loadXML(str);

            var oErr = xmlDom.parseError;

            if (oErr.errorCode != 0) {

                alert("解析XML資料錯誤:\n" + oErr.reason + "\nLine:" + oErr.line + "\nLinepos:" + oErr.linepos + "\nsrcText:\n" + oErr.srcText);

                return null;

            }

        }

        return xmlDom;

    }

<%--ff相容  判斷是否是ie浏覽器--%>

    function isIE(){

        if (window.navigator.userAgent.indexOf("MSIE")>=1)

            return true;

        else

            return false;

    }

    <%--格式化:去掉回車換行空格 2020-5-6    此方法是主要是格式化dom的innerHTML,不格式化\t\v\s等換行符會成為dom對象的childNodes,造成取節點值報錯的情況 --%>

    function formatStr(strXml){

        strXml = strXml.replace(/[\n\r\t]/g, '');

        strXml = strXml.replace(/>\s+</g, '><')

        //将<item>abc</item> 等xml節點轉換為大寫,轉換後為<ITEM>abc</ITEM>

        strXml = strXml.replace(/(<\/?)([a-z\d\:_]+)((\s+.+?)?>)/gi,function(s,a,b,c){return a+b.toUpperCase()+c;});

        return strXml;

    }

if(!window.ActiveXObject){

        XMLDocument.prototype.selectSingleNode = Element.prototype.selectSingleNode = function (xpath){

            var  x = this .selectNodes(xpath)

            if ( ! x || x.length < 1 ) return   null ;

             //去掉空格,回車,換行符

            var innerH = x[0].innerHTML;

            innerH = innerH.replace(/[\n\r\t]/g, '');

            innerH = innerH.replace(/>\s+</g, '><');

            x[0].innerHTML = innerH;

            return  x[ 0 ];

        }

        XMLDocument.prototype.selectNodes = Element.prototype.selectNodes = function (xpath){

            var  xpe  =   new  XPathEvaluator();

            var  nsResolver  =  xpe.createNSResolver( this .ownerDocument  ==   null   ?

                this .documentElement :  this .ownerDocument.documentElement);

            var  result  =  xpe.evaluate(xpath,  this , nsResolver,  0 ,  null );

            var  found  =  [];

            var  res;

            if(res = result.iterateNext()){

                found.push(res);

            }else{

                //如果無資料則xpath變為小寫再試 wyw 2020.4.26

                result  =  xpe.evaluate(xpath.toLowerCase(),  this , nsResolver,  0 ,  null );

            }

            while  (res  =  result.iterateNext())

                found.push(res);

            return  found;

        }

        XMLDocument.prototype.createElement = Element.prototype.createElement = function (nodeName){

            var node =  document.createElement(nodeName);

            return  this.appendChild(node);

        }

        //相容attachEvent方法 

        Element.prototype.attachEvent = function(event,func){

                event = event.replace('on','');

                this.addEventListener(event,func,false); 

        }  

        Object.defineProperty(Element.prototype, "documentElement", {

            configurable: true,

            enumerable:true,

            get: function (){

                var docXml = formatStr(this.innerHTML);

                var dso= loadXml(docXml);

                return dso.documentElement;

                }

            });

        //xmlDom 添加對象的xml屬性

        Object.defineProperty(XMLDocument.prototype, "xml", {

            configurable: true,

            get: function (){

                var oSerializer = new XMLSerializer();

                var xmlObj = oSerializer.serializeToString(this);

                return xmlObj;

                }

            });

        //html元素 添加對象的xml屬性

        Object.defineProperty(Element.prototype, "xml", {

            configurable: true,

            get: function (){

                return formatStr(this.innerHTML);

                }

            });

        Object.defineProperty(Element.prototype, "text", {

           configurable: true,

           get: function (){

            return this.textContent;

            },

           set: function (val){

            this.textContent = val;

            }

          }); 

    }

三、另外,火狐不支援 showModalDialog。用window.open()代替。注意的是dodal=yes 這個參數設定是不起作用的。

<%--2showModalDialog是早就廢棄了的api,這裡用window.open做相容--%>

    if(!window.showModalDialog){

        window.showModalDialog = function(uri, args, opts){

            opts = opts.replace(/:/g, '=')

                .replace(/;/g, ',')

                .replace('dialogWidth', 'width')

                .replace('dialogHeight', 'height')

                .replace('dialogheight', 'height')

                .replace('dialogtop', 'top')

                .replace('dialogleft', 'left')

                .replace('scroll', 'scrollbars');

            //讓視窗居中顯示 

            var iWidth = 0, iHeight = 0;

            var arr = opts.split(',');

            for(i=0;i<arr.length;i++){

                if(arr[i].indexOf('width')>=0){

                    iWidth = arr[i].split('=')[1];

                }

                if(arr[i].indexOf('height')>=0){

                    iHeight = arr[i].split('=')[1];

                }

            }

            iWidth = iWidth.replace('px', '');

            iHeight = iHeight.replace('px', '');

            var iTop = (window.screen.height-30-iHeight)/2; //獲得視窗的垂直位道置;

            var iLeft = (window.screen.width-10-iWidth)/2; //獲得視窗的水準位置;

            opts = "modal=yes,menubar=no,toolbar=no,location=no,top="+iTop+",left="+iLeft+","+opts; // 2020-5-11        

            var newWin = window.open(uri, '', opts);

            newWin.dialogArguments = args;

            return newWin;

        };

    }

主子視窗參數傳遞:

首頁面:

function btn_export_onclick(){

var rtn = showModalDialog("dlg_export.htm",null,"dialogWidth=500px;dialogheight=180px;status:no;help:no");

    //IE可直接傳回結果。ff需要傳回結果後再執行

    if(isIE()){

        exportData(rtn);

    }

function getRtn(rtn){

    exportData(rtn);

}

function exportData(rtn){

    if(rtn == null){

        return ;

    }

子頁面: 子頁面通過getRtn()方法傳值給首頁面,首頁面可通過該方法直接擷取值

function btn_export_onclick(){

  var arr = 'abc';

//window.returnValue = arr;  //2020-5-9 注釋

    if(!isIE()){

        window.opener.getRtn(arr);

    }else{

        window.returnValue = arr;

    }

    window.close();

繼續閱讀