• 解决方法也很简单,就是在 <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 旋转,所以会出现如下所示的问题。

    那些与 IE 相伴的日子-LMLPHP

    这里我们可以使用 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(-11); 
          ctx.drawImage(img, 00, 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 {
      height100px;
      width80%;
      margin20px auto;
      background-color: wheat;

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

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

    .wrapper-3 {
        height200px;
        width80%;
        margin20px auto;
        background-color: wheat;
        line-height200px;

        text-align: center; /* 主要代码 */
      }
      .flex-3 {
        width80px;
        line-height100px;
        background-color: pink;
        margin: auto 20px;
        height100px;
        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) 将代码转换成可以向后兼容、在低版本上也能够使用的的语法,比如这样:

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

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

    以在 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: {
                babelrcfalse,
                presets: [
                  [require.resolve("@babel/preset-env"), { modulesfalse }], // webpack 已做了模块化打包,所以此处 modules 里
                ],
                cacheDirectorytrue,
              },
            },
          },
        ],
      },
      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)

    看完两件事

    如果你觉得这篇内容对你挺有启发,我想邀请你帮我两件小事

    1.点个「在看」,让更多人也能看到这篇内容(点了在看」,bug -1 😊

    招贤纳士

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

    如果你想改变一直被事折腾,希望开始能折腾事;如果你想改变一直被告诫需要多些想法,却无从破局;如果你想改变你有能力去做成那个结果,却不需要你;如果你想改变你想做成的事需要一个团队去支撑,但没你带人的位置;如果你想改变既定的节奏,将会是“5 年工作时间 3 年工作经验”;如果你想改变本来悟性不错,但总是有那一层窗户纸的模糊… 如果你相信相信的力量,相信平凡人能成就非凡事,相信能遇到更好的自己。如果你希望参与到随着业务腾飞的过程,亲手推动一个有着深入的业务理解、完善的技术体系、技术创造价值、影响力外溢的前端团队的成长历程,我觉得我们该聊聊。任何时间,等着你写点什么,发给 ZooTeam@cai-inc.com

    本文分享自微信公众号 - 政采云前端团队(Zoo-Team)。
    如有侵权,请联系 support@oschina.cn 删除。
    本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

    06-17 09:28