react项目中遇到的浏览器兼容性问题(持续更新)

8,450 阅读3分钟

前言

以此篇作为 react 项目中遇到的浏览器兼容性问题的一个记录,另外如果你使用了 ant-design-pro/umi 请先按照官方文档设置要兼容的浏览器。

IE

HTML

  1. 线上的项目无法在 IE9-10 上打开的原因
    IE9 默认采用的文档模式是 IE7。解决方案:加入<meta http-equiv="X-UA-Compatible" content="IE=edge">,注意顺序:

    The X-UA-Compatible header is not case sensitive; however, it must appear in the header of the webpage (the HEAD section) before all other elements except for the title element and other meta elements.

  2. 默认使用 webkit 内核
    <meta name="renderer" content="webkit" />
  3. IE9-10favicon不显示
    因为 IE9-10 不支持 png 格式的 favicon,使用 ico 格式的 favicon

CSS

  1. IE9 不支持 flex 布局
    我试着找过 polyfill,只找到 flexibility 这个库可以通过 js 来模拟 flex 布局,但是我试了下发现没有效果,最终采用的方案是用 Modernizr 来判断浏览器对 flexbox 的兼容性,然后对于不兼容的使用其它布局方式,比如 table 布局。
  2. IE10 不支持新语法但是支持 2012版语法
    这个可以通过 autoprefixer 结合 browserslist 来实现打包的时候自动支持老语法,如果你使用的是 umiant-design-pro 可以直接设置 config.targets 为你要兼容的浏览器即可
  3. IE9 对于 css 文件的大小有限制
    超出 4095 条后后面的样式就不生效了,需要将大文件拆成小文件,可以使用 css-split-webpack-plugin 插件来实现,针对 umi 的话需要设置 imports 参数:
  4. IE9以下对 block 元素设置 display: inline-block 不管用
  5. IE10 flex: auto; flex-basis: auto;不管用
    子元素如果内容过多会撑开父元素,可以手动设置 flex-basis: 0%;
  6. 其它 flex 兼容性问题可以参考 github.com/philipwalto…
  7. css 属性 pointer-events 不兼容IE9
  8. IE9 设置 img height 为百分比并不能像chrome浏览器里一样按比例缩放,只能设置 width
  9. IE9-10 img 只设置 height 或 width 会有样式问题,最好都设置上

JS

  1. create-react-app 提供的 react-app-polyfill 只是对某些 ES6 的 API 做了兼容
    所以用 @babel/polyfill 替代了 react-app-polyfill
  2. dev 环境不支持 IE9
    在 IE9 上打开 dev 环境发现了很多问题,不仅有 webpack-dev-server 存在的兼容性问题,还有一些其它第三方库存在的兼容性问题,主要有以下问题(因为问题太多所以最后我放弃了IE9下的dev环境):
    • 首先是 bundle.js 文件里报 const map 未定义是因为 webpack-dev-server 从 2.7.1 后不支持 IE9
    • 如果是 vendor.js 文件里报 setPrototypeOf 未定义是因为 create-react-app 引入的 react-dev-utils/webpackHotDevClient 文件里面有一个 chalk 的包使用了这个 ES6 的方法,而 @babel/polyfill 的编译是基于__proto__,而 IE9 并不支持__proto__,所 以@babel/polyfill 无效
  3. IE9 控制台报错 TYPEError Cannot call a class as a function
    这是由于 babel 使用的 setPrototypeOf 方法的 polyfill 内部使用了 __proto__ 去实现而 IE9 不支持,所以可以用 setprototypeof 来模拟,记住要在页面加载时最先加载。
  4. IE10以下在 constructor 里面调用 this.props 会返回 undefined
    建议直接使用 constructor 传递的 props

Firefox

JS

  1. window.close() 无效
<a href="/new" target="_blank" ref="noopener noreferrer">a new page</a>

打开的页面无法通过 window.close() 关闭,解决方法是去掉 rel="noopener noreferrer"

参考资料