关于前端:那些与-IE-相伴的日子

3次阅读

共计 5986 个字符,预计需要花费 15 分钟才能阅读完成。

这是第 91 篇不掺水的原创,想获取更多原创好文,请搜寻公众号关注咱们吧~ 本文首发于政采云前端博客:那些与 IE 相伴的日子

前言

Internet Explorer(简称:IE)是微软公司 为了反抗 网景浏览器(NetscapeNavigator)从而投入开发,并于 1995 年推出的一款网页浏览器,已经一度成为同 Windows 零碎捆绑装置的流氓软件横行于世,也占据了极高的市场份额,但在近些年里,它却始终因为自身的落后而被泛滥用户和开发者诟病。

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

模仿 IE 版本环境

许多开发者们的电脑自身是 Mac 零碎,是无奈装置 IE 浏览器的,这个时候就须要装置虚拟机提供 Windows 环境测试 IE 浏览器下的成果了。然而装置的虚拟机比拟占用空间,这个时候,借用另一台 Windows 零碎的电脑,拜访 Webpack(或其余编译打包器)配置的局域网下的页面地址,以此调试,也不失为一个好抉择。

许多国产浏览器也提供了极速、兼容的双内核模式,极速模式下应用 Chrome 等非 IE 内核、兼容模式下应用 IE 内核,以应答不同页面的应用,关上控制台,能够切换模仿不同的 IE 版本(只管只是模仿,有些时候并不精确)。

兼容 IE 下的款式

其实很多浏览器不兼容的问题咱们都能够从这个网站 caniuse 上查问到,不止 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 合集》。

然而过多地依赖 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,外面曾经实现了常见的 History 路由的 Api。

在 IE 上应用 ES6

@babel/polyfill

IE 不反对许多 ES6 的语法,比方 Array.from(),Object.assign() 等常见函数,所以咱们能够应用工具链 Babel 中的 @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 图片向左或向右翻转

CSS Hack 合集

招贤纳士

政采云前端团队(ZooTeam),一个年老富裕激情和创造力的前端团队,隶属于政采云产品研发部,Base 在风景如画的杭州。团队现有 40 余个前端小伙伴,平均年龄 27 岁,近 3 成是全栈工程师,妥妥的青年风暴团。成员形成既有来自于阿里、网易的“老”兵,也有浙大、中科大、杭电等校的应届新人。团队在日常的业务对接之外,还在物料体系、工程平台、搭建平台、性能体验、云端利用、数据分析及可视化等方向进行技术摸索和实战,推动并落地了一系列的外部技术产品,继续摸索前端技术体系的新边界。

如果你想扭转始终被事折腾,心愿开始能折腾事;如果你想扭转始终被告诫须要多些想法,却无从破局;如果你想扭转你有能力去做成那个后果,却不须要你;如果你想扭转你想做成的事须要一个团队去撑持,但没你带人的地位;如果你想扭转既定的节奏,将会是“5 年工作工夫 3 年工作教训”;如果你想扭转原本悟性不错,但总是有那一层窗户纸的含糊… 如果你置信置信的力量,置信平凡人能成就不凡事,置信能遇到更好的本人。如果你心愿参加到随着业务腾飞的过程,亲手推动一个有着深刻的业务了解、欠缺的技术体系、技术发明价值、影响力外溢的前端团队的成长历程,我感觉咱们该聊聊。任何工夫,等着你写点什么,发给 ZooTeam@cai-inc.com

正文完
 0