JS跨浏览器兼容性解决思路及方案汇总
Posted 大前端深度精选
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JS跨浏览器兼容性解决思路及方案汇总相关的知识,希望对你有一定的参考价值。
上篇文章我们介绍了,处理CSS浏览器兼容性的4个解决方案:浏览器CSS样式初始化、浏览器私有属性,CSS hack语法和自动化插件,有兴趣的可以看看,链接放到本文结尾
本文主要介绍JS的跨浏览器兼容性主要解决思路和方案,主要包括这几个方面
浏览器兼容性问题查询途径
JS兼容性处理常用插件及类库
JS兼容性知识点汇总(兼容性处理的原生js写法)
浏览器兼容性问题查询途径
在Can I Use网站中,我们可以搜索某个CSS/JS特性的浏览器支持情况,如CSS的disp:flex,查询结果如下
鼠标移入某个浏览器版本上面,会有一些兼容性的描述,比如告诉你怎么进行兼容
我们再搜索一下JS的添加事件监听方法addEventListener,结果如下
同样的,鼠标移入浏览器版本上面,可以看到一些兼容性的解决方法提示,非常方便
通过这个网站,我们就可以做到对每个浏览器的支持情况,做到心中有数,是前端人员不可不知的一个网站。
兼容性处理常用插件及类库
有人说前端学起来比较简单,那是因为90%以上的脏活累活,都被各种类库作者干了,我们只不过是进行调用,面向api编程而已。兼容性处理也有很多类库,这里给大家介绍几个比较常用的。
Html5shiv.js
html5shiv是解决IE6,IE7,IE8不识别html5新增html标签的问题,其实这个不应该算JS兼容性处理,应该是Html的兼容性处理,不过因为Html的兼容性问题毕竟少,不再单独介绍,特在此简单说明。
一般采用条件hack的方式引入Html5shiv.js
<!--[if lt IE 9]>
<script src="//cdn.bootcss.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<![endif]-->
还有一点需要注意,在页面中调用Html5shiv.js文件,必须添加在页面的head元素内,因为IE浏览器必须在元素解析前知道这个元素,所以这个js文件不能在页面底部调用。
Respond.js
Respond.js 是一个快速、轻量的 polyfill,用于为 IE6-8 以及其它不支持 CSS3 Media Queries 的浏览器提供媒体查询的 min-width 和 max-width 特性,实现响应式网页设计,如:
@media screen and (min-width: 480px){
/** ...styles for 480px and up go here **/
}
在所有css后面引入该文件,但是越早引入越好,在ie下面看到页面闪屏的概率就越低,一般我们在head中,同时引入Html5shiv.js和Respond.js
<!--[if lt IE 9]>
<script src="//cdn.bootcss.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="//cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
jQuery/Zepto
jQuery大家肯定都非常熟悉了,在没有使用3大框架(React、Vue、Angular)的时候,简直是前端利器,而且jQuery帮我们做了一些兼容性的封装,让我们使用起来不用考虑那么多。
jQuery从2.x开始已经不兼容IE6、7、8了,如果要兼容IE9以下的浏览器,需要使用jQuery 1.x 版本
我们随便看几个jQuery中关于JS兼容性处理的代码
//添加事件监听
...
if ( elem.addEventListener ) {
elem.addEventListener( type, eventHandle, false );
} else if ( elem.attachEvent ) {
elem.attachEvent( "on" + type, eventHandle );
}
...
//ajax兼容性处理
function createStandardXHR() {
try {
return new window.XMLHttpRequest();
} catch ( e ) {}
}
//IE8一下
function createActiveXHR() {
try {
return new window.ActiveXObject( "Microsoft.XMLHTTP" );
} catch ( e ) {}
}
Babel
虽然ES6标准已经通过很多年了,但是目前仍然有很多浏览器不支持,下图为ES6新语法Promise的浏览器支持情况,但是作为前端,我们现在必须要熟悉ES6语法并用其进行开发了,目前主要通过Babel将ES6语法转换为ES5代码。
babel是一个转译器,感觉相对于编译器compiler,叫转译器transpiler更准确,因为它只是把同种语言的高版本规则翻译成低版本规则,而不像编译器那样,输出的是另一种更低级的语言代码。
但是和编译器类似,babel的转译过程也分为三个阶段:parsing、transforming、generating,以ES6代码转译为ES5代码为例,babel转译的具体过程如下:
ES6代码输入 ==》 babylon进行解析 ==》 得到AST ==》 plugin用babel-traverse对AST树进行遍历转译 ==》 得到新的AST树 ==》 用babel-generator通过AST树生成ES5代码
我们可以通过webpack结合babel-loader来实现,具体配置方式不展开了。
JS兼容性知识点汇总(兼容性处理的原生js写法)
获取滚动条位置
//chrome中document.body.scrollTop始终为0,而safari中 document.documentElement.scrollTop始终为0
let scrollTop = document.documentElement.scrollTop || document.body.scrollTop
事件绑定
if (obj.addEventListener) {
obj.addEventListener(event,fn,fase);
}else{
//兼容IE8以下
obj.attachEvent("on"+event,fn);
}
event事件对象
document.onclick = function(e){
//IE8以下不会传入参数e,e为undefined
var e = e||window.event;
//获取target的兼容写法,后面的为IE
var target=e.target||e.srcElement;
}
阻止浏览器默认事件
function prevent(event){
if (event.preventDefault) {
event.preventDefault();
}else{
//兼容IE
event.returnValue = false;
}
}
阻止事件冒泡
function stop(event){
if (event.stopPropagation) {
event.stopPropagation()
}else{
//兼容IE
event.cancleBubble = true;
}
}
相关阅读:
以上是关于JS跨浏览器兼容性解决思路及方案汇总的主要内容,如果未能解决你的问题,请参考以下文章