抛弃 IE8,这是我们做的一个艰难的决定

距离我们抛弃 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 = /MSIE\s(\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。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏分享达人秀

四大组件的纽带——Intent

前面学习Activity时己经多次使用了 Intent,当一个Activity需要启动另一个Activity时, 程序并没有直接告诉系统要启动哪个Act...

2265
来自专栏世界第一语言是java

Android N 7.0、8.0 上自动安装apk问题

如果安装报错,可能是临时文件访问路径没有配置,或者百度上找到的安装代码是旧版本的,7.0以后不在支持,文章最下面有适配的代码。

1452
来自专栏女程序员的日常

STM8S——Flash program memory and data EEPROM

1、简介   STM8S内部的FLASH程序存储器和数据EEPROM是由一组通用寄存器来控制的;所以我们可以通过这些通用寄存器来编程或擦除存储器的内容、设置写保...

2921
来自专栏程序员互动联盟

【Android基础】Android中的Intent详解

前言: 每个应用程序都有若干个Activity组成,每一个Activity都是一个应用程序与用户进行交互的窗口,呈现不同的交互界面。因为每一个Acticity...

4207
来自专栏梦里茶室

Activity篇章参考

附上学习这部分知识的时候收集的一些比较好的链接: Task and backStack|Android Developer adb shell dumpsys ...

1989
来自专栏向治洪

软件更新时候出现和原包名冲突

如果你是一个开发人员,那么出现这个问题可能是因为,较旧的版本你是使用eclipse自动发布到模拟器上的,而eclipse自动发布时使用的是一个测试用签名,这个签...

1936
来自专栏Android干货

Android项目实战(四十):Andoird 7.0+ 安装APK适配

3176
来自专栏DeveWork

10个使用 Foundation 框架开发的WordPress 主题推荐

上一篇文章介绍了《Foundation:高级的响应式前端框架》,今天则介绍10个使用 Foundation 框架开发的WordPress 主题,对于想研究 Fo...

30410
来自专栏封碎

在一个apk中调用另外一个apk中的activity 博客分类: Android小技巧 AndroidCC++C#Web

    其实,这本来是一件很简单的事情,但是我发现很多人问我这个问题,所以写篇小文章供参考。

1142
来自专栏刘望舒

你真的了解Activity的启动模式吗?

当面试官说请你介绍一下activity启动模式,大多数人都能整两句,什么栈顶复用啊栈内复用啊,不过,你确定你真的懂启动模式吗?

1364

扫码关注云+社区

领取腾讯云代金券