IE瀏覽器版本檢測小結

IE瀏覽器版本檢測小結

最近在PC web前端IE兼容性方面,做了很多工作,包括解決IE兼容性的BUG、IE低版本polyfill解決方案和IE瀏覽器下的提示。IE兼容的問題多而雜,且IE各個版本存在的問題也不一樣,總結起來的話比較費勁;但針對IE的解決,都要涉及到IE版本的檢測,本文對常用方法做一些總結。


何時需要IE版本檢測

  1. IE兼容性BUG
    在IE低版本瀏覽器中,會有很多意想不到的BUG,大部分是樣式BUG,因爲IE低版本對css的一些屬性的支持情況不盡相同,倘若頁面中和現代瀏覽器用同一種css樣式文件,很大概率會出現樣式不一致甚至錯亂的情況。而不同的IE版本,又不盡相同,所以最好的解決辦法是對不同的IE版本做區分使用不同的樣式文件。

  2. IE低版本polyfill
    IE不同版本對H5的新特性以及js的一些API支持情況也不盡相同,比如,最近解決的placeholder屬性polyfill,IE9及以下版本不支持<input>的 placeholder 屬性。
    這裏寫圖片描述
    這裏寫圖片描述
    polyfill可以通過在input上覆蓋浮動元素實現placeholder效果,input輸入值時隱藏浮動元素。但IE10以上,可以直接使用原生的placeholder屬性,不需要進行處理,這就需要進行版本檢測對實現方法進行區分。

  3. IE瀏覽器下的提示
    有些情況下,不需要去解決IE不支持的問題,可能是策略上只需要支持現代瀏覽器,也可能是一些高級效果沒辦法通過polyfill實現。這時可以簡單在IE低版本瀏覽器打開頁面時,給出提示,例如:
    這裏寫圖片描述

IE版本檢測方法

html條件註釋

對於IE兼容樣式問題,常用的解決辦法是針對不同的IE版本使用不同的樣式文件進行處理。而針對某個IE版本的樣式文件,不希望在其他版本下引入,這時使用條件註釋可以很方便的進行區分。

<!-- 默認先調用css.css樣式表 -->
<link rel="stylesheet" type="text/css" href="css.css" />

<!-- IE下調用1.css樣式表 -->
<!--[if IE]>
<link rel="stylesheet" type="text/css" href="1.css" />
<![endif]-->

<!-- 如果IE瀏覽器版本小於6,調用2.css樣式表 -->
<!--[if lt IE 6]>
<link rel="stylesheet" type="text/css" href="2.css" />
<![endif]-->

條件註釋語句在其它瀏覽器裏,完全就是一堆註釋,但在IE裏卻不會。IE會分析裏面的版本號,並根據版本號確定要不要解析裏面內容。
其中有一些語法:

  • lte: 就是Less than or equal to的簡寫,也就是小於或等於的意思。
  • lt: 就是Less than的簡寫,也就是小於的意思。
  • gte: 就是Greater than or equal to的簡寫,也就是大於或等於的意思。
  • gt: 就是Greater than的簡寫,也就是大於的意思。
  • !: 就是不等於的意思
    根據這些語法就可以輕鬆區分不同IE版本了:
<!--[if IE]> / 如果瀏覽器是IE /
<!--[if IE 5]> / 如果瀏覽器是IE 5 的版本 /
<!--[if IE 6]> / 如果瀏覽器是IE 6 的版本 /
<!--[if IE 7]> / 如果瀏覽器是IE 7 的版本 /
<!--[if lt IE 8]> / 如果瀏覽器是低於IE 8 的版本 /
<!--[if gte IE 9]> / 如果瀏覽器是大於等於IE 9 的版本 /

注:條件註釋是在 IE5.0 以後才被IE支持的,對於IE5以前的瀏覽器是無效的;且對高版本IE10以上也無效

條件註釋配合腳本控制

有些情況下,需要更靈活的腳本控制,而不僅僅是區分樣式文件的引入。這時可以在js腳本中實現檢測IE版本的方法,一種實現方法即是根據條件註釋的原理進行判斷:

var isIE = function(){
    var b = document.createElement('b')
    b.innerHTML = '<!--[if IE]><i></i><![endif]-->'
    return b.getElementsByTagName('i').length === 1
}

首先生成了一個b元素,設置它的innerHTML爲IE條件註釋,註釋裏只有一個空的標籤,然後讀取裏面的元素 i , 如果被解析爲dom元素,則 length 爲1;被當做註釋,未被解析,則沒法獲取這個元素。
進而可以更加靈活地檢測不同版本的IE瀏覽器:

var isIE = function(ver){
    var b = document.createElement('b')
    b.innerHTML = '<!--[if IE ' + ver + ']><i></i><![endif]-->'
    return b.getElementsByTagName('i').length === 1
}
if(isIE(6)){
    // IE 6
}
// ...
if(isIE(9)){
    // IE 9
}

根據瀏覽器內核信息檢測

js的全局對象window子屬性 navigator.userAgent (用戶代理屬性),這個屬性是包含了瀏覽器的相關信息,包括我們需要的瀏覽器內核信息。navigator.userAgent這個值取出來是個字符串,可以通過string的 indexOf 方法或者正則匹配來驗證關鍵字符,達到檢測瀏覽器版本的目的。
首先看看各個瀏覽器版本的 navigator.userAgent 值:

// FireFox userAgent
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:60.0) Gecko/20100101 Firefox/60.0"
// Chrome userAgent
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36"
// safari userAgent
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/11.1.1 Safari/605.1.15"

// IE Edge userAgent
"Mozilla/5.0 (Windows NT 10.0; WOW64; x64) AppleWebKit/537.36 (KHTML,like Gecko) Chrome/51.0.2704.79 Safari/537.36 Edge/14.14393"
// IE 11 userAgent
"Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko"
// IE 10 userAgent
"Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 10.0; WOW64; Trident/7.0)"
// IE 9 userAgent
"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 10.0; WOW64; Trident/7.0)"
// IE 8 userAgent
"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 10.0; WOW64; Trident/7.0)"
// IE 7 userAgent
"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 10.0; WOW64; Trident/7.0)"
//IE6 ...
...

根據解析userAgent字符串的信息,就可以區分出不同瀏覽器的版本:

function BrowserType() 
 { 
   var userAgent = navigator.userAgent; 
   var isIE = userAgent.indexOf("compatible") > -1 && userAgent.indexOf("MSIE") > -1; //判斷是否IE瀏覽器 
   var isEdge = userAgent.indexOf("Edge") > -1; //判斷是否IE的Edge瀏覽器
   var isFF = userAgent.indexOf("Firefox") > -1; //判斷是否Firefox瀏覽器 
   var isSafari = userAgent.indexOf("Safari") > -1 && userAgent.indexOf("Chrome") == -1; //判斷是否Safari瀏覽器 
   var isChrome = userAgent.indexOf("Chrome") > -1 && userAgent.indexOf("Safari") > -1 && !isEdge; //判斷Chrome瀏覽器 

   if (isIE)  
   { 
      var reIE = new RegExp("MSIE (\\d+\\.\\d+);"); 
      reIE.test(userAgent); 
      var fIEVersion = parseFloat(RegExp["$1"]); 
      if(userAgent.indexOf('MSIE 6.0')!=-1){
        return "IE6";
      }else if(fIEVersion == 7) 
        { return "IE7";} 
      else if(fIEVersion == 8) 
        { return "IE8";} 
      else if(fIEVersion == 9) 
        { return "IE9";} 
      else if(fIEVersion == 10) 
        { return "IE10";} 
      else if(userAgent.toLowerCase().match(/rv:([\d.]+)\) like gecko/)){ 
            return "IE11";
        } 
      else
        { return "0"}//IE版本過低
    }//isIE end 

    if (isFF) { return "FF";} 
    if (isSafari) { return "Safari";} 
    if (isChrome) { return "Chrome";} 
    if (isEdge) { return "Edge";} 
  }//myBrowser() end 

注:MDN網站並不推薦使用這種方法進行瀏覽器檢測,同時也給出了理由
這裏寫圖片描述

特徵檢測

如上所述,MDN推薦使用“特徵檢測”來檢測web新特性的支持情況。即某些屬性在不同版本瀏覽器下支持情況是不同的,同時也可以直接用特徵檢測來判斷瀏覽器版本:

// 低版本IE瀏覽器才具有window.ActiveXObject屬性,支持ie6-11
    function isIE() { //ie?
        if (window.ActiveXObject || "ActiveXObject" in window){
            return true;
         }else{
            return false;
         }
    }

然而,使用特徵檢測來判斷IE瀏覽器版本,並不通用,且無法精確區分IE版本。MDN推薦使用特徵檢測,也只是希望使用特徵檢測新特徵的支持情況,從而進行一些polifill的處理。例如,File API在IE低版本是不支持的,所以需要進行判斷:

if (window.FileReader) {
  // supported
} else {
  // not-supported
}

進而對瀏覽器不支持的情況進行處理。

綜上,相信看過這些不同的瀏覽器檢測方法後,大家對於何種情況下用何種方法已經有了自己的想法。對於IE的兼容性處理確實比較頭疼,但方法總比困難多,掌握更多的方法,才能更快解決問題。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章