专栏首页采云轩那些与 IE 相伴的日子

那些与 IE 相伴的日子

这是第 91 篇不掺水的原创

本文首发于政采云前端团队博客:那些与 IE 相伴的日子 https://www.zoo.team/article/days-with-ie

前言

Internet Explorer(简称:IE)是 微软公司 (https://baike.baidu.com/item/微软公司/732128) 为了对抗 网景浏览器 (https://baike.baidu.com/item/网景浏览器)(NetscapeNavigator)从而投入开发,并于 1995 年推出的一款网页浏览器,曾经一度成为同 Windows 系统捆绑安装的流氓软件横行于世,也占据了极高的市场份额,但在近些年里,它却一直因为本身的落后而被众多用户和开发者诟病。

如今,即便是连微软公司自己都放弃了更新 IE,但一众 Web 开发者们为了部分仍在坚持使用 IE 浏览器的用户,却依然不得不向下兼容,笔者也是其中的一员,本篇文章记录了我在工作期间为了兼容 IE( IE9及以上 )做过的一些调整。

模拟 IE 版本环境

许多开发者们的电脑本身是 Mac 系统,是无法安装 IE 浏览器的,这个时候就需要安装虚拟机提供 Windows 环境测试 IE 浏览器下的效果了。然而安装的虚拟机比较占用空间,这个时候,借用另一台 Windows 系统的电脑,访问 Webpack (https://webpack.docschina.org/) (或其他编译打包器)配置的局域网下的页面地址,以此调试,也不失为一个好选择。

许多国产浏览器也提供了极速、兼容的双内核模式,极速模式下使用 Chrome 等非 IE 内核、兼容模式下使用 IE 内核,以应对不同页面的使用,打开控制台,可以切换模拟不同的 IE 版本(尽管只是模拟,有些时候并不准确)。

兼容 IE 下的样式

其实很多浏览器不兼容的问题我们都可以从这个网站 caniuse (https://www.caniuse.com/) 上查询到,不止 IE,还包括 Safari、Firefox 以及他们在安卓系统中对应的浏览器兼容能力也被很好的总结在这里了。然而,我们是很难一次性查完所有的差异点再投入开发的,这里分享几个我在开发中遇到的问题,以及对应的解决方法吧。

1)图片定宽不定高会变形

在我平常做首屏 Banner 大图的时候,有时候为了快,直接写一个宽度 width: 1200px 就觉得万事大吉了,在 Chorme 上确实也表现良好,不负所望,但是当测试到 IE9、IE10 时,都会存在一个问题是图片变形,如下图所示。

当我打开 IE 浏览器的 DOM 资源管理器的时候发现,IE 浏览器对我 <img /> 标签多添加了一段这样的属性: width="824" height="300",而这个宽度和高度是从哪里来的呢?我选中下载下来的图片,右击查看详情,发现这个图片文件本身的宽度和高度就是 824px 和 300px,于是答案便可以知晓了。

当我设置图片标签的 src 的时候, IE 浏览器自动将原图片的宽、高设置成了 <img /> 的属性,这样导致我使用 CSS 只设置宽度为 1200px 而没有设置高的时候,<img /> 的生效高度便是原图的高度 300px。而 Chrome 对 <img /> 标签什么都没有添加,所以标签的高度 height 也就是按照图片等比例缩放后的高度,不会变形。

  • Chrome 下的表现
  • IE 下的表现

解决方法也很简单,就是在 <img /> 标签的的 class 样式里,再添加一个简单的 height: auto;,同时对宽高进行设置,覆盖掉原标签自动添加的宽度和高度,这样就可以解决变形的问题了。

2)IE 下 8 位色值不生效

在之前的开发中,我都习惯了使用 6 位色值,也不曾出现过问题,直到有一次,运营同学反馈在组件配置平台下选中了某个颜色,却一直不生效,通过排查问题,才发现了原来输出的色值是 8 位,而正是这多余的两位,在 IE 浏览器下并不通用。

我们知道,CSS 颜色使用组合了红、绿、蓝颜色值 (RGB) 的十六进制 (hex) 表示法进行定义,十六进制值使用三个双位数来编写,并以 # 符号开头(如:#FF0000),同时, Chrome 浏览器支持 8 位色值(如 #FF0000ee),最后两位表示不透明度 Alpha 值,其中 00 表示不透明度为 0,也就是全透明状态,FF 表示不透明度 100%,也就是全不透明状态,但在 IE 浏览器下不支持。

IE 情况下,使用 8 位色值,不但最后两位的不透明度无法生效,反而整个颜色设置都不能生效,下面是一个简单的 Demo 来模拟这种情况,标题的颜色设置不生效,所以呈现出默认的黑色状态。

解决方法也比较简单,在这种场景下,不透明度不是必须的,可以删除掉最后两位,仅使用 6 位色值即可。如果实在需要不透明度,我们可以使用 rgba 的格式,用最后一位值来实现透明度,如 background-color: rgba(255,0,0,0.3),即使在 IE9 上也可以表现良好。

3)处理左右镜像

IE9 支持了 CSS3 的许多属性,但还是有许多力所不能及的地方。比如,有一次的开发场景是希望在标题的两边做出对称的两种图样,于是我对这张图拷贝出来的第二份设置了 transform:rotateY(180deg); 让图片绕 Y 轴旋转,IE9 虽然已经支持了 trasform 2D 旋转,但是并不支持 trasform 3D 旋转,所以会出现如下所示的问题。

这里我们可以使用 IE9 支持的 canvas 画布将坐标轴翻转 ,绘制图像,就能得到一个左右对称的图片了。Html 中需要对原始 <img /> 标签进行宽度和高度的显式设置,才能保证 <canvas> 中有准确的宽高。代码如下。

getRotateImg = (imgSourceId = '') => {
    const imgNode = document.getElementById(imgSourceId);
    const canvas = document.createElement('canvas'); 
    canvas.setAttribute('id', 'canvas');
    // 设置 canvas 的宽高,防止变形 
    canvas.setAttribute('width', imgNode.style.width); 
    canvas.setAttribute('height', imgNode.style.height); 

    const width = parseInt(imgNode.style.width);
    const height = parseInt(imgNode.style.height);
    
    var ctx = canvas.getContext('2d');
    var img = new Image();
    img.src = imgNode.src;
    
    imgNode.parentNode.appendChild(canvas); 
    img.onload = function() {
      console.log(imgNode.style.width);
      // 将坐标原点移动到画布最右端,使反向图片向左绘制,呈现在画布范围内
      ctx.translate(width, 0);
      //左右镜像翻转坐标系
      ctx.scale(-1, 1); 
      ctx.drawImage(img, 0, 0, width, height);
    }
 }

实际效果如图所示。

4)放弃 Flex 布局

在初识 Flex 布局(弹性布局)的时候,会喜欢上它的灵活简单,但是 IE9 下并不支持 Flex 布局,我们可以用其他方式来代替。

比如我们可以这样通过 display: tabledisplay: table-cell 实现一个简单的等分效果,在这种情况下,传统的 margin 无法提供外边距,我们可以使用 border-space 代替。

<div class="wrapper-2">
  <div class="flex-2">4 等分</div>
  <div class="flex-2">4 等分</div>
  <div class="flex-2">4 等分</div>
  <div class="flex-2">4 等分</div>
</div>

CSS 代码

.wrapper-2 {
  height: 100px;
  width: 80%;
  margin: 20px auto;
  background-color: wheat;

  display: table;  /* 主要代码 */
  border-spacing: 30px;  /* 主要代码 */
}
.flex-2 {
  background-color: pink;
  padding: 10px;
  text-align: center;
  border: solid 2px purple;
  
  display: table-cell; /* 主要代码 */
}

或者使用 text-align: center,vertical-align: middle 配合 display: inline-block 达到类似的效果,如下:

.wrapper-3 {
    height: 200px;
    width: 80%;
    margin: 20px auto;
    background-color: wheat;
    line-height: 200px;

    text-align: center; /* 主要代码 */
  }
  .flex-3 {
    width: 80px;
    line-height: 100px;
    background-color: pink;
    margin: auto 20px;
    height: 100px;
    border: solid 2px purple;
    text-align: center;

    display: inline-block;   /* 主要代码 */
    vertical-align: middle;  /* 主要代码 */
    
  }

关于 CSS Hack

CSS Hack 的原理是根据不同浏览器和浏览器不同的版本对 CSS 的解析不同,分别书写不同的代码加以应对。常见的写法有 3 种:条件注释法、CSS 属性前缀法、选择器前缀法,一般写 Hack 的顺序是:从最新版本到低版本,比如:新版本、IE(10/9/8)、IE(7/6),具体写法可以参考这篇文章 CSS Hack 合集 (https://www.w3cschool.cn/lugfe/lugfe-vxfp25zq.html)。

但是过多地依赖 CSS hack 会导致代码非常的不整洁,也可能会对后续的兼容留下隐患,所以实际很少使用。

例如这些:

只在 IE 下生效
<!--[if IE]>
这段文字只在IE浏览器显示
<![endif]-->

只在 IE6 下生效
<!--[if IE 6]>
这段文字只在IE6浏览器显示
<![endif]-->

IE9 不支持 History 路由

在单页面应用中,存在着前端路由的概念,哈希路由兼容性好,但是 URL 总是存在着/#会让人觉得有些不好看,于是我们想到了清爽简洁的 History 路由。

然而,在 IE 9 条件下,由于缺少 window.history 对象,自然也不能调用 history.pushStatehistory.replaceState 方法,所以 Chrome 下能够正常使用的 History 路由模式不能生效。这个时候我们有几种解决方案了,一是选择哈希路由,二是直接做成多页面应用,跳转时刷新整个页面,也可以选择使用 history.js (https://github.com/browserstate/history.js/) ,里面已经实现了常见的 History 路由的 Api。

在 IE 上使用 ES6

@babel/polyfill

IE 不支持许多 ES6 的语法,比如 Array.from(),Object.assign() 等常见函数,所以我们可以使用工具链 Babel (https://www.babeljs.cn/docs/) 中的 @babel/polyfill (https://www.babeljs.cn/docs/babel-polyfill) 将代码转换成可以向后兼容、在低版本上也能够使用的的语法,比如这样:

// 我们书写的原始代码
[1, 2, 3].map((n) => n + 1);

// 经过转换后的代码
[1, 2, 3].map(function(n) {
  return n + 1;
});
npm install --save-dev @babel/core @babel/cli @babel/preset-env
npm install --save @babel/polyfill

在 node 环境中使用

require("babel-polyfill");

在 es6 中使用

import "babel-polyfill";

在 webpack 中使用

module.exports = {
 entry: ["babel-polyfill", "./app/js"] 
};

以在 webpack 中配置为例,webpack.config.js 代码如下:

var path = require("path");

module.exports = {
  entry: {
    entry: ["@babel/polyfill", "./index.js"], // 在入口文件 index.js 前面加入 "@babel/polyfill" 这个配置
  },
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "bundle.js",
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ["style-loader", "css-loader"],
      },
      {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader", // 需要安装 babel-loader 此配置可将所有 js,jsx 后缀的文件进行转换
          options: {
            babelrc: false,
            presets: [
              [require.resolve("@babel/preset-env"), { modules: false }], // webpack 已做了模块化打包,所以此处 modules 里
            ],
            cacheDirectory: true,
          },
        },
      },
    ],
  },
  plugins: [],
};

总结

以上是我在兼容 IE(IE9 及以上) 过程中踩过的坑和进行的调整了。技术是死的,应用却是活的,我们应当掌握常见的兼容能力,但有时候,绞尽脑汁地向下兼容反而不如换一个更灵活、成本更低的方式表达。我们期待着多年以后,用户们能够放弃 IE,拥抱更敏捷好用的浏览器,迎接一个新的时代。

参考文档

JS 实现兼容 IE 图片向左或向右翻转(https://blog.csdn.net/weixin_30920091/article/details/98890519)

CSS Hack 合集 (https://www.w3cschool.cn/lugfe/lugfe-vxfp25zq.html)

本文分享自微信公众号 - 政采云前端团队(Zoo-Team),作者:北渊

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2021-03-09

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

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Windows7 寿终正寝:那些一并消逝的微软软件你知多少?

    本月,一代经典操作系统微软Windows 7正式迎来了生命周期的完结。微软宣布,此后将不再为Win7提供任何形式的更新,包括安全更新、稳定性更新和功能更新;而仍...

    周三不加班
  • 微软杀死了曾经全球第一的浏览器

    今年以来,Edge浏览器切换到Chromium生态并重装上阵,并强势地捆绑推送给了几乎每一个Win 10用户。

    开发者技术前线
  • 昨天全国哀悼日,全站变灰,我们都这么做

    原文链接:https://juejin.im/post/5e86e221e51d4546ce27b99c

    歪马
  • Magicodes.IE 3.0重磅设计畅谈

    Magicodes.IE导入导出通用库,支持Dto导入导出、模板导出、花式导出以及动态导出,支持Excel、Csv、Word、Pdf和Html。

    雪雁-心莱科技
  • 那些“混”大学的,你们好日子结束了

    导读:6月,在新时代全国高等学校本科教育工作会议上,教育部部长陈宝生发话:中国教育“玩命的中学、快乐的大学”现象应该扭转,对中小学生要有效“减负”,对大学生要合...

    华章科技
  • 《那些年,我在乙方的日子 -- 神谕篇NO1》

    某个夏日的午后,窗外知了在大声鸣叫。而我却在睡梦中跟基友一起吃鸡,正准备抢空投时 。手机突然铃声响起,惊醒后一看是领导电话,一下子回到了现实中。心想又得去公司吃...

    田帅萌
  • IE浏览器主页被劫持,如何解决主页被篡改问题?

    前几天号主的电脑的指纹解锁功能突然不能用了,号主以为是驱动没更新到最新版导致的,去官网下载最新的驱动都安装上了也是不行,后面找Dell客服两个小时也没有找到最终...

    FreeRonin
  • 【思考】为何弃用jQuery?(下)

    关于“下“的内容却迟迟没有动手,其中也有诸多事情干扰,也可以认为是借口,但我自己其实也是还没有想清楚该如何去说这个事。

    林小帅
  • 携号转网来临前,那些“狼来了”的日子

    2019年3月,北京的初春尚有寒意。金融街31号跟往常一样,熙攘穿梭。4号上午九点过后,杨杰起身坐电梯到大厅,等待他的是一起战斗过的老同事、老部下们。今天杨杰将...

    镁客网

扫码关注云+社区

领取腾讯云代金券