JS跨浏览器兼容性解决思路及方案汇总

Posted 大前端深度精选

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JS跨浏览器兼容性解决思路及方案汇总相关的知识,希望对你有一定的参考价值。

上篇文章我们介绍了,处理CSS浏览器兼容性的4个解决方案:浏览器CSS样式初始化、浏览器私有属性,CSS hack语法和自动化插件,有兴趣的可以看看,链接放到本文结尾

本文主要介绍JS的跨浏览器兼容性主要解决思路和方案,主要包括这几个方面

  • 浏览器兼容性问题查询途径

  • JS兼容性处理常用插件及类库

  • JS兼容性知识点汇总(兼容性处理的原生js写法)

浏览器兼容性问题查询途径


在Can I Use网站中,我们可以搜索某个CSS/JS特性的浏览器支持情况,如CSS的disp:flex,查询结果如下



鼠标移入某个浏览器版本上面,会有一些兼容性的描述,比如告诉你怎么进行兼容


JS跨浏览器兼容性解决思路及方案汇总


我们再搜索一下JS的添加事件监听方法addEventListener,结果如下


JS跨浏览器兼容性解决思路及方案汇总


同样的,鼠标移入浏览器版本上面,可以看到一些兼容性的解决方法提示,非常方便


JS跨浏览器兼容性解决思路及方案汇总


通过这个网站,我们就可以做到对每个浏览器的支持情况,做到心中有数,是前端人员不可不知的一个网站。


兼容性处理常用插件及类库


有人说前端学起来比较简单,那是因为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跨浏览器兼容性解决思路及方案汇总的主要内容,如果未能解决你的问题,请参考以下文章

JS常用框架及各自特点

Web开发中常见的兼容性解决方案(持续汇总...)

js异步问题怎么解决

javascript常见兼容问题汇总js(主要针对IE)

跨浏览器实现placeholder效果的jQuery插件

前端开发中常见的浏览器兼容性问题及解决方案