|
前言
作为一名菜鸡前端,我经常被safari的浏览器兼容性折磨,所以在此做一个曾解决过的兼容性问题总结,给日后不了解如何处理兼容性问题的前端同学提供一个思路。
低版本IOS Safari浏览器不兼容ES6语法
这是我首次跟safari浏览器打交道,在跟别的公司对接H5页面的时候发现的问题,他们的app最低可支持ios10的系统安装,他们的测试在用ios11.2的系统打开我们的H5页面时便出现了白屏,身边的同事也都没有用低版本的ios的,同时我也不知道页面报的是什么错误,此时一度陷入困境,在不清楚问题的情况下去解决报错,贸然更改代码与配置太过冒险,公司的电脑用的是Windows系统,安装虚拟机来还原低版本的ios环境或许是解决这个问题的方法。
先去黑苹果社区去下载一个macOs的镜像,这里我选择的版本是macOs11.1,虚拟机安装mac系统详情可见该篇文章
安装mac系统是为了使用Xcode,Xcode可以模拟ios的环境。mac环境都准备完毕后,进入Xcode设置里面的Preferences,选择Components,下载需要的ios版本。
运行对应的ios版本即可实现在Windows上打开ios设备(模拟),解决了没有低版本ios真机的痛点。
打开模拟器后发现低版本的ios系统的safari确实打不开H5页面,在项目的入口index.html文件中加入如下代码
<script type=&#34;text/javascript&#34; src=&#34;//cdn.jsdelivr.net/npm/eruda&#34;></script>
<script>eruda.init();</script>引入一个小插件,可以实现在移动端设备上打开控制台。
打开控制台后问题终于水落石出,Unexpected token &#39;...&#39;. Expected a property name,ES6拓展语法导致的代码报错。
在项目中的.babelrc文件中加入如下配置
&#34;presets&#34;: [
[
&#34;@babel/preset-env&#34;,
{
&#34;useBuiltIns&#34;:&#34;usage&#34;,
&#34;corejs&#34;:{
&#34;version&#34;:&#34;3&#34;,
&#34;proposal&#34;:true
},
&#34;targets&#34;:{
&#34;chrome&#34;:&#34;60&#34;,
&#34;safari&#34;:&#34;10&#34;
}
}
],
&#34;@babel/preset-react&#34;
],
&#34;plugins&#34;: [
&#34;@babel/plugin-transform-runtime&#34;,
]配置更改后重新编译发布,低版本ios设备可正常访问
至此,首个safari浏览器兼容性问题得以解决,整个过程的关键在于如何复现问题,发现报错。如果有低版本ios设备的同学可以绕过安装虚拟机macOs系统去使用Xcode模拟器,直接引入查看控制台的插件,即可看到报错。
Safari浏览器不支持YY-MM-DD hh:mm:ss时间格式
项目中做了一次时间格式调整,所有的时间需要带时分秒,调整完以后用户发现某款产品无法计算年龄,调整了项目中的代码,计算年龄的时候使用YY-MM-DD的格式,从而解决了这个问题。
Safari浏览器不支持正则的零宽断言
在项目中为了替换#{}的内容,使用了零宽断言,导致safari浏览器又双报错了,故换了一种正则匹配方式,下面是我变更后的代码,有兴趣的同学可以参考一下(我的正则写的烂,可以酌情吐槽一下)。
// 根据环境变量替换链接中的url
function transformUrl(url){
/**正则表达式 */
// const re = new RegExp(&#39;(?<=\#\{).*?(?=\})&#39;, &#39;g&#39;); //匹配#{}里面的内容 零宽断言写法
const re = new RegExp(&#39;\#\{(.*?)\}&#39;, &#39;g&#39;); //匹配#{}里面的内容
const tUrl = _.map([...new Set(url.match(re))], item => { // 去重
return item.slice(2,-1) // 去除#{}
})
let nUrl = _.cloneDeep(url);
_.forEach(tUrl, item => {
if(window?.env?.[item]){
// const reg = new RegExp(`(?<=\#\{)\(${item}\)\*\?(?=\})`, &#39;g&#39;); //匹配#{}里面的内容 零宽断言写法
// const exReg = new RegExp(`\#\{\(${window.env[item]}\)\*\?\}`, &#39;g&#39;); // 匹配#{},目的去除#{} 零宽断言写法
const reg = new RegExp(`\#\{(${item})\}`, &#39;g&#39;); //匹配#{}里面的内容
const exReg = new RegExp(`\#\{\(${window.env[item]}\)\*\?\}`, &#39;g&#39;); // 匹配#{},目的去除#{}
const replaceUrl = _.replace(nUrl, reg, window.env[item]);
const newRepUrl = _.replace(replaceUrl, exReg, window.env[item]);
nUrl = newRepUrl;
}
})
return nUrl;
}小结
兼容性问题不同于开发过程中遇到的bug,需要慢慢发现并消化,多方面的去思考解决方案,可以从配置或代码层面入手;作为一个前端开发,平时也不应当只以谷歌浏览器作为开发视角,也可以多关注一下其他的浏览器。最后推荐一个网站,用于查看各个浏览器的兼容性,祝各位前端同学都能妥善处理各种兼容性问题。 |
|