拋棄 IE8,這是我們做的一個艱難的決定

  • 2019 年 12 月 4 日
  • 筆記

本文作者:IMWeb 結一 原文出處:IMWeb社區 未經同意,禁止轉載

距離我們拋棄 IE6、7 已經兩年多了,我們就一直眼巴巴的想著什麼時候可以拋棄 IE8,然後就在上個月,我們決定開始拋棄 IE8 了,原因是我們的 IE8 用戶已經掉到了 1% 以下。

當然本著用戶體驗至上,總得給這些用戶一個提示吧。最直接的當然是直接判斷 userAgent 中有無「MSIE 8」欄位,但是畢竟「talk is cheap」,原生的 IE 肯定是沒問題的,不過對於那些愛恨交織的國產雙核瀏覽器,我實在是不清楚。於是簡單測試了幾個,如下圖:

這就是幾種雙核瀏覽器 IE 內核時的 userAgent,有的標識了瀏覽器名稱如圖一的 QQBrower;有的呢只有 Trident 標識,如圖二;有的呢既有 Trident 標識也有 MSIE 的標識,如圖三。

經過反覆查閱資料,得到了兩個關鍵資訊:

  • 從 IE8 開始有了 Trident 標識,其各種版本對應如下:
    • Trident/7.0:IE11
    • Trident/6.0:IE10
    • Trident/5.0:IE9
    • Trident/4.0:IE8
  • 從 IE11 開始又去掉了 MSIE 標識,所以不能通過 MSIE 來判斷了

這樣我們就大概明白了,上面我們截圖中的 Trident/7.0 表示是 IE11,但是為什麼圖三又有了"MSIE 7.0"兼容模式呢?而上面的兩個沒有兼容模式的到底是 IE11 還是 IE 幾?

再者我這只是測試了三個雙核瀏覽器,還有那麼多國產的雙核瀏覽器又該是什麼?

如何檢測通知升級

首先我們的目標是檢測 IE8- 提示升級。當然這是當前的目標,但是我們有個更長遠的目標,以後IE9、10要被拋棄的時候,我們希望也可以用。

方法如下:

直接使用「MSIE」 欄位判斷

對於原生的 IE 這招是沒問題的,但是對於國產雙核瀏覽器的 IE 內核,因為太多(且userAgent 說變就變),根本沒有一一去驗證,不知道是否能行得通。

提示原生的升級,提示雙核的切換為webkit內核

原生的很好檢測,但是雙核的檢測經驗證暫時實現不了,因為有些雙核瀏覽器中就沒有該瀏覽器的特徵,如上面的圖二及圖三

反過來,把不要升級的先剔除

我們可以先把不需要升級提示先圈起來,然後再做進一步判斷,程式碼如下:

let userAgent = navigator.userAgent; //取得瀏覽器的userAgent字元串  let isShowModal = false;    let pat1 = /Chrome|Firefox|Safari|Edge|Opera|Webkit/g;  // 得到IE版本  let pat2 = /MSIEs(d+)./g;  // 得到IE內核版本,國產雙核瀏覽器可能只有Trident欄位  let pat3 = /Trident/(d)./g;  // IE6、IE7、IE8(Trident 4.0)、IE9(Trident 5.0)、IE10(Trident 6.0)、IE11(Trident 7.0)  let oT = {'t4': 8, 't5': 9, 't6': 10, 't7': 11};    // 8 表示ie8  // 9 表示ie9  // 10 表示ie10  function detect(num) {    if (pat1.test(userAgent)) {      return ;    } else {      let v; // IE 版本號      if (userAgent.indexOf('Trident') >  -1) { // 先檢測 Trident        v = pat3.test(userAgent) ? parseInt(RegExp["$1"]) : 0;          isShowModal = oT['t'+v] < num ? true : false;      }      if (userAgent.indexOf('compatible') > -1 && userAgent.indexOf('MSIE') > -1) {        v = pat2.test(userAgent) ? parseFloat(RegExp["$1"]) : 0;        isShowModal = v < num ? true : false;      }    }  }    function noticeModal(msg) {    if (isShowModal) {      alert('該升級瀏覽器了');      alert(userAgent);    } else {      alert('你的瀏覽器版本很高級,不用幹啥')    }  }    function init (num) {    let i = num || 9;    detect(i);    noticeModal();  }    init(); // 默認 IE8- 通知升級    init(10); // IE9- 通知升級

根據一些特性去檢測

當然上面的有點複雜,我們還可以根據一些特性去檢測:

// ie8 不支援 border-radius  // ie9 不支援 transition  // ie10 不支援最新版本的 flexbox    class TestIE {    constructor() {      this.ele = document.createElement('div');    }    ie8() {      return this.el.style.borderRadius === undefined; // 8- 不支援 border-radius    }    ie9() {      return this.el.style.transition === undefined; // 9- 不支援 transition    }    ie10() { // 注意不要用在移動端      return this.ele.style.order === undefined; // 10- 不支援新版本的 flexbox    }  }

該辦法相對來說比較簡單,雖然可能有一定的誤差(如不支援 border-radius 的可能不是IE8-),但是提示升級是沒有什麼問題的,所以推薦使用。

組件

當然上面的程式碼只是解決方案的思路,還是有點粗糙,接下來就是搞個組件,要用的時候 npm install 下就可以了。所以現在我要去寫組件了,bye。

Tags: