IE8兼容問題(1)

背景

今天在做項(xiàng)目時(shí)發(fā)現(xiàn)IE8的console.log返回錯(cuò)誤,以及IE8不支持getElementsByClassName方法,并且在對(duì)document.getElementByClassName賦值給變量后無法調(diào)用,因此寫下本篇文章用于記錄今日的問題,并且探究問題的解決方案。

問題

1.console.log返回錯(cuò)誤

<script>
    console.log(1);
</script>

以上代碼段運(yùn)行在IE8/9內(nèi)核環(huán)境下會(huì)返回console未定義異常。??

IE8 console錯(cuò)誤截圖

但是在我打開F12開發(fā)者工具之后刷新頁面又不會(huì)出現(xiàn)以上異常,這讓我煩惱不已。然后在網(wǎng)絡(luò)上搜索資料發(fā)現(xiàn)IE8/9在開啟開發(fā)者工具時(shí)不會(huì)構(gòu)造console對(duì)象,因此會(huì)出現(xiàn)異常。

解決方案:

1.刪除在程序內(nèi)部的console對(duì)象
2.為console對(duì)象初賦值。

//將console對(duì)象在console未定義時(shí)初始化為一個(gè)空方法對(duì)象,避免IE8/9報(bào)錯(cuò)
window.console=window.console||(function(){
      var c = {};
      c.log=c.info=c.assert=c.error=c.dir=c.clear=c.profile=c.warn=
      c.profileE=function(){}
      return c;
})();

2.IE8不支持document.getElementsByClassName

今日做開發(fā)的時(shí)候?qū)懥艘粋€(gè)IE8的兼容實(shí)現(xiàn),在對(duì)DOM操作時(shí)使用了document.getElementsByClassName來獲取對(duì)象,然而卻返回了錯(cuò)誤,當(dāng)時(shí)一臉懵逼,沒想到IE8連如此通用的方法都沒支持,先撒撒氣,然后就查看兼容性實(shí)現(xiàn)方法。。。??

//所書寫的代碼段
var delegator = documents.getElementsByClassName('content-left')[0],//報(bào)錯(cuò)
      isIE = typeof document.all === 'undefined'?false:true;//判斷是否是IE
if(isIE){
IEFunc();               
}
else{
OtherFunc();
}
解決方案:

1.通過自實(shí)現(xiàn)的代碼解決方案(大多參考網(wǎng)上的解決方案)。

//通過遍歷所有標(biāo)簽進(jìn)行判斷處理(粗暴的處理方式,在對(duì)于大量標(biāo)簽頁面的處理明顯是不可取的)
document.getElementsByClassName = document.getElementsByClassName||function(value){
    var arr = [];
    var all = document.getElementsByTagName('*');
    for(var i=0,len=all.length;i<len;i++){
        var temp = all[i].getAttribute('class');
        if(temp&&temp.indexOf(value)>=0){
            arr.push(all[i]);
        }
    }
    return arr;
};

2.其他大神或者框架的處理方案。(本小節(jié)內(nèi)容多摘自司徒正美的博客)
The Ultimate getElementsByClassName方案,作者為Robert Nyman,05年實(shí)現(xiàn)。

//三個(gè)參數(shù)都是必需的,查找一網(wǎng)頁中5007個(gè)類名為“cell”的元素,IE8歷時(shí)1828 ~ 1844毫秒
function getElementsByClassName(oElm, strTagName, strClassName){
//oElm DOM對(duì)象,strTagName 查找對(duì)象的Tag名,strClassName 查找對(duì)象的類名

    var arrElements = (strTagName == "*" && oElm.all)? oElm.all :
        oElm.getElementsByTagName(strTagName);
    //oElm.all可獲取所有DOM對(duì)象, (Tips1)
    
    var arrReturnElements = new Array();
    strClassName = strClassName.replace(/\-/g, "\\-");
    var oRegExp = new RegExp("(^|\\s)" + strClassName + "(\\s|$)");
    //用于判斷類名的正則,匹配開頭或空格+類名+空格或結(jié)尾

    var oElement;
    for(var i=0; i < arrElements.length; i++){
        oElement = arrElements[i];
        if(oRegExp.test(oElement.className)){
            arrReturnElements.push(oElement);
        }
    }
    return (arrReturnElements);
}

Tips1:typeof document.all 在IE下返回'object',在其他瀏覽器下返回'undefined'。

另一個(gè)實(shí)現(xiàn),由Dustin Diaz(《JavaScript Design Patterns》的作者)提供,但兼容性不如上面的,不支持IE5。

//后兩參數(shù)是可靠的,查找一網(wǎng)頁中5007個(gè)類名為“cell”的元素,IE8歷時(shí)78毫秒,IE6歷時(shí)125~171毫秒
var getElementsByClass = function(searchClass,node,tag) {
        var classElements = new Array();
        if ( node == null )
                node = document;
        if ( tag == null )
                tag = '*';
        var els = node.getElementsByTagName(tag);
        var elsLen = els.length;
        var pattern = new RegExp("(^|\\s)"+searchClass+"(\\s|$)");
        for (i = 0, j = 0; i < elsLen; i++) {
                if ( pattern.test(els[i].className) ) {
                        classElements[j] = els[i];
                        j++;
                }
        }
        return classElements;
}

還有個(gè)更古老級(jí)的,司徒正美前輩從prototype.js1.01版本中找到的,它能支持多個(gè)類名的查找(上面兩個(gè)不行)。它不支持IE5,效率一般般,但作為最早的框架之一,它已經(jīng)做得很好,其他框架還沒有想到這個(gè)呢!

function getElementsByClassName(className, element) {
    var children = (element || document).getElementsByTagName('*');
    var elements = new Array();

    for (var i = 0; i < children.length; i++) {
        var child = children[i];
        var classNames = child.className.split(' ');
        for (var j = 0; j < classNames.length; j++) {
            if (classNames[j] == className) {
                elements.push(child);
                break;
            }
        }
    }

    return elements;
}

后續(xù)還介紹了DOMTreeWalker 和 XPath的解決方案,但是我還沒又這方面的知識(shí)就不在此處貼出了,感興趣的同學(xué)可以瀏覽上面司徒正美的博客。接下來給出司徒正美前輩給出的最終解決方案:

//下列代碼可以解決‘red cell’ 對(duì)<span class="cell red"></span>等特殊class情況的檢索
var getElementsByClassName = function (searchClass, node,tag) {
  if(document.getElementsByClassName){
    var nodes =  (node ||   document).getElementsByClassName(searchClass),result = [];
      for(var i=0 ;node = nodes[i++];){
        if(tag !== "*" && node.tagName === tag.toUpperCase()){
          result.push(node)
        }
      }
      return result
    }else{
      node = node || document;
      tag = tag || "*";
      var classes = searchClass.split(" "),
      elements = (tag === "*" && node.all)? node.all : node.getElementsByTagName(tag),
      patterns = [],
      current,
      match;
      var i = classes.length;
      while(--i >= 0){
        patterns.push(new RegExp("(^|\\s)" + classes[i] + "(\\s|$)"));
      }
      var j = elements.length;
      while(--j >= 0){
        current = elements[j];
        match = false;
        for(var k=0, kl=patterns.length; k<kl; k++){
          match = patterns[k].test(current.className);
          if (!match)  break;
        }
        if (match)  result.push(current);
        }
      return result;
    }
  }

3.document.method賦值給變量后調(diào)用報(bào)錯(cuò)

在寫兼容性代碼時(shí)曾考慮將document.method賦值給變量的方式來返回兼容性結(jié)果,然而在chrome瀏覽器運(yùn)行時(shí)異常拋出Illegal invocation

//測(cè)試代碼
var getClass = document.getElementsByClassName;
getClass('class');
chrome錯(cuò)誤內(nèi)容

然而在IE8下運(yùn)行上述方法奇跡般的成功了。。。??

IE8內(nèi)核下運(yùn)行結(jié)果

IE9下測(cè)試則報(bào)錯(cuò)。

IE9內(nèi)核下運(yùn)行結(jié)果

而在chrome下使用

 getClass.call(document,'class'); //運(yùn)行成功 圖片就不上了 有興趣的同學(xué)可以自己測(cè)試

然而非設(shè)置this為document而未其他Dom節(jié)點(diǎn)時(shí)就會(huì)報(bào)錯(cuò),其中細(xì)節(jié)搜索資料并為找到原因,如果有大牛還請(qǐng)講解原由。??

總結(jié)

上面總結(jié)了今日所遇到的IE8兼容性問題,有自己探索的結(jié)果也有網(wǎng)上搜羅的資料,雖然有些內(nèi)容沒有啥可用性但是作為程序員一定要有專研和探究的精神。?? 如上述問題有錯(cuò)誤或還請(qǐng)大牛貼上講解地址或者留言,感激不敬??,本文目的在于分享與交流,如要引用還望指明出處,謝謝。
轉(zhuǎn)眼間要12點(diǎn)了,第一次寫如此長的文章??,希望記錄今日的問題,該洗洗睡了,明天還要上班咧??。
行文倉促,如有問題還望指出。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容