jquery兼容实验

时间:2020-11-28 06:55:33

使用jquery时候,曾经遇到两个问题:

1.一个页面里,使用了很多基于jquery的前端ui库,但是各个库之间对jquery的依赖的版本不一样,有的依赖jquery1.4,jquery2.0用不了;有的依赖jquery2.0,jquery1.4用不了。这下就麻烦了,如果先在项目里引入jquery1.4,然后初始化我们的控件,再引入jquery2.0,之前用jquery1.4初始化的控件就全用不了了,能不能在一个页面里同时引用两个jquery,不同的控件用不同的jquery呢?

2.一个页面里,想同时使用了两个ui库,比如easyui和jqueryui,但是两个ui库冲突了,主要因为他们控件定义的名字是一样的。比如一个创建了jQuery.fn.a,另一个ui库也创建了一个jQuery.fn.a,后一个就会把前一个覆盖掉,那有没有可以解决的方法呢?

其实两个问题都是可以解决的。首先我们开发jq插件都时候,都喜欢使用“(function($){})(jQuery);”这样的一段代码,将我们真正的代码包起来,这样的做法主要有两个目的:

1.是为因为js的作用域是函数级的,只有使用函数,才能使得一些局部变量不会“污染”全局作用域或者上层作用域。

2.就是为了更好地兼容jq不同的版本,因为通过参数传递,window上的jQuery变成了别名$,而这个$与window上的$并不是一个东西,即便以后window上的$发送了变化,这个域里的$还是最初传进来的对象。

那么我们可以从这里看出,只要在引入第二个jq前,将第一个jq起个别名,就可以继续使用之前引入的jq了。

如:var $1_4 = $;

<script src="//cdn.bootcss.com/jquery/1.4.0/jquery.js"></script>
<!-- 基于1.4的插件初始化 -->
<script>
var $1_4 = $
</script>
<script src="//cdn.bootcss.com/jquery/2.0.0/jquery.js"></script>
<!-- 基于2.0的插件初始化 -->

这样使用1.4的插件使用$1_4,使用2.0的插件时候使用$,当然在引入2.0后,就没办法再引入基于1.4jq的插件了。

如果自己使用$1_4不是很习惯,我们可以类比$插件的定义来一个“(function($){})(jQuery);”

(function($){
  //使用1.4版本的插件,这里的$就是$1_4
  $("#id")...
})($1_4);

当前,如果还是想让$和jQuery的版本变回1.4,有没有解决办法呢?

当然有了,最蠢的办法就是继续类似命名$1_4这样的方式换名字罢了,但是有没有更优雅的方式呢?

有,这才说到noConflict方法,事实上jquery在覆盖window的原有$和jQuery对象前,做了一个副本_$和_jQuery保存在自己的域中,当如果用户想要让jquery让出$和jQuery的值,将其还原为原来的版本时,可以使用noConflict方法。如:

<script src="//cdn.bootcss.com/jquery/1.4.0/jquery.js"></script>
<script>
console.log($.fn.jquery);
</script>
<script src="//cdn.bootcss.com/jquery/2.0.0/jquery.js"></script>
<script>
console.log($.fn.jquery);
//这里true和false的区别是,如果给true,不仅$要还原,jquery也要还原
$.noConflict(false);
console.log($.fn.jquery);
</script>

输出为:

1.4
2.0
1.4

这样执行noConflict后,$的版本还原为1.4了。事实上noConflict的返回值就是当前的jQuery对象,之前的“var $1_4 = $”也可以使用“var $1_4 = $.noConflict()”代替。

然后是第二个问题,两个同名的插件冲突,如何解决?

其实所有插件都是定义jQuery.fn或者jQuery上,jQuery也是一个js对象。所谓的jq插件,其实就是对jquery的命名空间扩展,如果之前已经定义了这个命名空间,再次定义肯定会覆盖之前那个。这里我想到了一个最笨的方法,就是同事引入两个jQuery对象,将同名插件分别定义在不同的jQuery对象上。至于怎么才能同事引入两个jQuery对象呢?答案很简单,参考jquery版本冲突的解决方案,你都可以同时使用jq1.4和jq2.0了,还不能同时引入两个jq吗?