前言
以此篇作为 react 项目中遇到的浏览器兼容性问题的一个记录,另外如果你使用了 ant-design-pro/umi 请先按照官方文档设置要兼容的浏览器。
IE
HTML
- 线上的项目无法在 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.
- 默认使用 webkit 内核
<meta name="renderer" content="webkit" /> - IE9-10favicon不显示
因为 IE9-10 不支持 png 格式的 favicon,使用 ico 格式的 favicon
CSS
- IE9 不支持 flex 布局
我试着找过 polyfill,只找到 flexibility 这个库可以通过 js 来模拟 flex 布局,但是我试了下发现没有效果,最终采用的方案是用 Modernizr 来判断浏览器对 flexbox 的兼容性,然后对于不兼容的使用其它布局方式,比如 table 布局。 - IE10 不支持新语法但是支持 2012版语法
这个可以通过 autoprefixer 结合 browserslist 来实现打包的时候自动支持老语法,如果你使用的是 umi 或 ant-design-pro 可以直接设置 config.targets 为你要兼容的浏览器即可 - IE9 对于 css 文件的大小有限制
超出 4095 条后后面的样式就不生效了,需要将大文件拆成小文件,可以使用 css-split-webpack-plugin 插件来实现,针对 umi 的话需要设置 imports 参数:
- IE9以下对 block 元素设置 display: inline-block 不管用
- IE10 flex: auto; flex-basis: auto;不管用
子元素如果内容过多会撑开父元素,可以手动设置 flex-basis: 0%; - 其它 flex 兼容性问题可以参考 github.com/philipwalto…
- css 属性 pointer-events 不兼容IE9
- IE9 设置 img height 为百分比并不能像chrome浏览器里一样按比例缩放,只能设置 width
- IE9-10 img 只设置 height 或 width 会有样式问题,最好都设置上
JS
- create-react-app 提供的 react-app-polyfill 只是对某些 ES6 的 API 做了兼容
所以用 @babel/polyfill 替代了 react-app-polyfill - 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 无效
- IE9 控制台报错
TYPEError Cannot call a class as a function
这是由于 babel 使用的 setPrototypeOf 方法的 polyfill 内部使用了 __proto__ 去实现而 IE9 不支持,所以可以用 setprototypeof 来模拟,记住要在页面加载时最先加载。 - IE10以下在 constructor 里面调用 this.props 会返回 undefined
建议直接使用 constructor 传递的 props
Firefox
JS
- window.close() 无效
<a href="/new" target="_blank" ref="noopener noreferrer">a new page</a>
打开的页面无法通过 window.close() 关闭,解决方法是去掉 rel="noopener noreferrer"