后台管理项目浏览器兼容性一览
IE / EdgeFirefoxChromeOpera360QQ
(图)360浏览器
(图)QQ浏览器
IE10, Edge
last 2 version
last 2 version
latest
latest
latest
一、框架、配置与依赖库
我们的后台管理系统项目是基于 Ant Design 框架开发的,并使用了 Ant Design Pro 脚手架搭建,因此根据 Ant Design 的浏览器兼容性来说,是可以完全支持现代浏览器以及 IE 11、Edge 的,而对于 IE 9/10 也会有一定的支持。
对于 IE 9/10,我们可以通过 polyfill 解决部分兼容问题。
一般来说可以使用babel-preset-env来处理,但由于我们的后台项目使用了 Umi,也可以直接通过配置 targets 来实现。targets 的配置会自动引入 polyfill 和做语法转换,配置的 targets 会合并到默认值,所以不需要重复配置。
export default {
targets: {
ie: 9,
},
};
由于使用了 polyfill 进行语法转换,需要注意引用依赖库的时候必须是引用本地库,而不能引用外部 CDN,因为外部 CDN是直接引用而没有经过 polyfill 的,这会导致 ES6语法无法转为 ES5语法,而 IE 10及以下版本不支持或者不完全支持 ES6 的。
export default {
externals: {
// if is production externals react react-dom and bizcharts
// ...(NODE_ENV === 'production'
// ? { react: 'React', 'react-dom': 'ReactDOM', bizcharts: 'BizCharts' }
// : {}),
},
}
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
</body>
</html>
同样,由于 IE 10及以下版本不支持 ES6语法,我们在引用依赖库的时候,库里面的代码必须是已被转换成 ES5语法的。在默认配置下,node_modules里面所有库都不会在项目打包的时候进行语法转换,所以如果有一些库代码只有原始 ES6版本的,可以配置项目打包的时候也对这些库进行语法转换。
在我们的项目中,sooncity和 cn-validator这两个库是需要转换的,如果在开发过程中遇到其他库也是用的 ES6语法引起IE浏览器报错,也可以加入到 extraBabelIncludes配置中。
export default {
extraBabelIncludes: [
path.resolve("node_modules/sooncity/src"),
path.resolve("node_modules/cn-validator/lib")
]
}
注:webGL的原因IE 10及以下版本是不支持的
另外,IE 10及以下版本对 umi-plugin-react中dva的动态加载配置不支持,如果配置了动态加载浏览器会报错。
这个问题暂时未有解决方案。可参考这个ISSUE继续追踪。
因此如果要实现浏览器的 IE 10兼容,只能禁用 dva的动态加载
export default {
plugins: [
'umi-plugin-react',
{
dva: {
dynamicImport: undefined,
}
}
]
};
最后,还需要注意依赖库的版本。有些依赖库在新版本中优化了浏览器兼容性问题,对我们开发来说���非常方便的。
如果项目的 package-lock.json 文件没有提交到 git 仓库,容易引起线上编译部署时依赖包版本不可控的问题,建议把 package-lock.json 从 .gitignore 中移除并提交。
二、代码兼容性优化
在开发过程中,可以注意一些保证浏览器兼容的代码细节,以下是一些比较常见的问题:
正则表达式
Chrome / FireFox等现代浏览器支持ES6语法,因此也支持构建 RegExp的时候使用正则表达式,例如:
console.log("1+2".replace(new RegExp(/+/, 'g'), ' '));
但对于 IE,这种写法是不支持的,可以改成以下写法:
console.log("1+2".replace(new RegExp("\+", 'g'), ' '));
console.log("1+2".replace(/+/g, ' '));
ScrollBar
IE / Chrome / FireFox 等不同内核的浏览器对滚动条的写法都是不一样的,支持修改的属性也不一样。基本写法如下:
/* Chrome */
/* 滚动条 */
::-webkit-scrollbar {
width: 4px;
height: 4px;
background-color: transparent;
}
/* 滚动条轨道 */
::-webkit-scrollbar-track {
background-color: transparent;
border-radius: 4px;
}
/* 定义滑块 */
::-webkit-scrollbar-thumb {
background-color: green;
border-radius: 24px;
}
/* 滚动条上的按钮 (上下箭头) */
::-webkit-scrollbar-button{
}
/* 滚动条没有滑块的轨道部分 */
::-webkit-scrollbar-track-piece {
}
/* 当同时有垂直滚动条和水平滚动条时交汇的部分 */
::-webkit-scrollbar-corner {
/* FireFox */
/* 滚动条属性只对指定元素作用,不会自动继承,需要对所有需要的元素设置滚动条属性,或者全局对所有元素设置 */
.scroller {
scrollbar-width: thin; // 滚动条宽度,可选 auto / thin / none
scrollbar-color: #0A4C95 #C2D2E4; // 滑块颜色 滚动条颜色
}
/* IE */
/* 滚动条样式 */
.scroller {
scrollbar-arrow-color: #f4ae21; // 三角箭头的颜色
scrollbar-face-color: #333; // 立体滚动条的颜色
scrollbar-3dlight-color: #666; // 立体滚动条亮边的颜色
scrollbar-highlight-color: #666; // 滚动条空白部分的颜色
scrollbar-shadow-color: #999; // 立体滚动条阴影的颜色
scrollbar-darkshadow-color: #666; // 立体滚动条强阴影的颜色
scrollbar-track-color: #666; // 立体滚动条背景颜色
scrollbar-base-color:#f8f8f8; // 滚动条的基本颜色
}
/* 控制元素内容溢出时滚动条的行为, 可选值如下: */
/* auto:初始值等同于inherit */
/* scrollbar:出现传统滚动条 */
/* -ms-autohiding-scrollbar:出现会自动隐藏的滚动条 */
/* none:不出现滚动条 */
.scroller {
-ms-overflow-style: scrollbar;
}
注:IE Edge 已删除旧版本 IE 中滚动条相关的非标准CSS属性配置,因此无法进行任何滚动条属性修改。
在处理滚动条样式的时候,还会遇到滚动条宽高度不确定性的问题。这个时候我们可以巧妙利用 vw / vh 和 %。当赋值 width: 100vw 的时候,所得到的宽度是包含滚动条宽度的,而width: 100%的时候则不包括,在适当的时候用适合的写法,或者计算两者只差,都有助于我们开发需要的样式。
渐变色
CSS3 的 gradient 属性在 IE 9 及以下版本是无效的,可以通过 IE 滤镜添加渐变效果:
.button {
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#000000', endColorstr='#ffffff',GradientType=0 ); // 兼容 IE 9
background: -moz-linear-gradient(top, #000000 0%, #ffffff 100%);
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#000000), color-stop(100%,#ffffff));
background: -webkit-linear-gradient(top, #000000 0%,#ffffff 100%);
background: -o-linear-gradient(top, #000000 0%,#ffffff 100%);
background: -ms-linear-gradient(top, #000000 0%,#ffffff 100%);
background: linear-gradient(to bottom, #000000 0%,#ffffff 100%);
}
Chrome / FireFox等现代浏览器支持ES6语法,因此也支持构建 RegExp的时候使用正则表达式,例如:
console.log("1+2".replace(new RegExp(/+/, 'g'), ' '));
Flex布局
IE 9 及以下版本不支持 display: flex 布局,需要通过其他样式写法来回避这个问题。
跨域请求
IE 9 及以下版本不支持带 header 的跨域请求,可以通过服务端渲染等其他手段回避这个问题。Placeholder
IE 9 及以下版本不支持 / 标签的 placeholder 属性。可以通过配置 value 并监听 Focus 和 Blur 事件实现类似 placeholder 的效果。
文字溢出
IE / Firefox 不支持 text-overflow: ellipsis 的自动继承,需要在该元素中做对应配置。
.button {
display: block;
max-width: 116px;
height: 32px;
text-overflow: ellipsis;
-ms-text-overflow: ellipsis;
overflow: hidden;
> span {
display: block;
max-width: 116px;
text-overflow: ellipsis;
-ms-text-overflow: ellipsis;
overflow: hidden;
}
}
拖放事件
IE 使用 dragEvent.dataTransfer.setData 方法时,key 必须是 'Text',对于其他浏览器没有限制。
dragEvent.dataTransfer.setData('Text', JSON.stringify(model))
文件读取
IE 不支持 FileReader 的 readAsBinaryString 方法,如果需要前端处理非文本文件的数据读取,可以采用 readAsArrayBuffer 代替,并对 arrayBuffer 进行转换处理。
if (!FileReader.prototype.readAsBinaryString) {
FileReader.prototype.readAsBinaryString = function (fileData) {
var binary = '';
var pt = this;
var reader = new FileReader();
reader.onload = function (e) {
var bytes = new Uint8Array(reader.result);
var length = bytes.byteLength;
for (var i = 0; i < length; i++) {
binary += String.fromCharCode(bytes[i]);
}
if(pt.target) {
pt.target.result = binary
} else {
pt.target = { result: binary };
}
pt.onload(pt);
}
reader.readAsArrayBuffer(fileData);
}
}
style 写入
我们想给元素的 style 赋值的时候,如果直接给 style 赋值,IE 会报 “strict 模式下不允许分配到只读属性” 这个错误。可以通过以下方法解决:
ele.style = 'height: 6px;width: 200px;' // 错误写法,在严格模式下ele.style会被认定为只读属性。
ele.style.height = '6px' // 正确写法,给某个样式赋值
ele.className = 'classA' // 正确写法,把需要改写的样式写在某个类名下