欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

关于jQuery库冲突的完美解决办法

程序员文章站 2022-06-07 10:21:51
前言 一次面试中面试官问到jquery和别的库冲突怎么解决?虽然以前看过,但是我已经不记得了。 我的思路就是如果让我来设计,那我就用一个默认值$,不传参数,那就用$,最...

前言

一次面试中面试官问到jquery和别的库冲突怎么解决?虽然以前看过,但是我已经不记得了。

我的思路就是如果让我来设计,那我就用一个默认值$,不传参数,那就用$,最后就挂载在window.$上,传参数就用传入名字,比如传入jq,那我就挂载在window.jq上。

var mycontrol="jq";
(function(name){
 var $=name ||"$"; //name存在$的值就是name的值,不存在或为null,$的值为字符串"$"
 console.log($);
 window[$]=function(){
 alert("123");
 }
})(mycontrol)
window[mycontrol]();

事实上这肯定不是jquery解决冲突的办法了。那就看看jquery怎么解决冲突吧。

jquery多个版本或和其他js库冲突主要是常用的$符号的冲突。

一、冲突的解决

1、同一页面jquery多个版本冲突解决方法

<body>
<!-- 引入1.6.4版的jq -->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.js"></script>
<script> var jq164 = jquery.noconflict(true); </script>
<!-- 引入1.4.2版的jq -->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.js"></script>
<script> var jq142 = jquery.noconflict(true); </script>

<script>
(function($){
 //此时的$是jquery-1.6.4
 $('#');
})(jq164);
</script>
 
<script>
jq142(function($){
 //此时的$是jquery-1.4.2
 $('#');
});
</script>
 
</body>

2、jquery库在其他库之后导入

jquery noconflict() 方法会释放会 $ 标识符的控制,这样其他脚本就可以使用它了。

1、可以通过jquery全名替代简写的方式来使用 jquery

在其他库和jquery库都加载完毕后,可以在任何时候调用jquery.noconflict()函数来将变量$的控制权移交给其他javasript库。然后就可以在程序里将jquery()函数作为jquery对象的制造工厂。

<script src="prototype.js" type="text/javascript"></script>
<script src="jquery.js" type="text/javascript"></script>

<p id="pp">test---prototype</p>
<p>test---jquery</p>

<script type="text/javascript">
jquery.noconflict();  //将变量$的控制权让渡给prototype.js,全名可以不调用。
jquery(function(){   //使用jquery
 jquery("p").click(function(){
 alert( jquery(this).text() );
 });
});
//此处不可以再写成$,此时的$代表prototype.js中定义的$符号。

$("pp").style.display = 'none'; //使用prototype
</script>

2、自定义一个快捷方式

noconflict() 可返回对 jquery 的引用,可以把它存入自定义名称,例如jq,$j变量,以供稍后使用。

这样可以确保jquery不会与其他库冲突,同时又使用自定义一个快捷方式。

<script type="text/javascript">
var $j = jquery.noconflict(); //自定义一个比较短快捷方式
$j(function(){   //使用jquery
 $j("p").click(function(){
 alert( $j(this).text() );
 });
});

$("pp").style.display = 'none'; //使用prototype
</script>

3、在不冲突的情况下仍然用$

如果想在jquery 代码块使用 $ 简写,不愿意改变这个快捷方式,可以把 $ 符号作为变量传递给 ready 方法。这样就可以在函数内使用 $ 符号了 , 而在函数外,依旧不得不使用 "jquery"。

<script type="text/javascript">
jquery.noconflict(); //将变量$的控制权让渡给prototype.js
jquery(document).ready(function($){
 $("p").click(function(){ //继续使用 $ 方法
 alert( $(this).text() );
 });
});
//或者如下
jquery(function($){   //使用jquery
 $("p").click(function(){ //继续使用 $ 方法
 alert( $(this).text() );
 });
});
</script>

或者使用ief语句块,这应该是最理想的方式,因为可以通过改变最少的代码来实现全面的兼容性。

在我们自己写jquery插件时,应该都使用这种写法,因为我们不知道具体工作过程中是如何顺序引入各种js库的,而这种语句块的写法却能屏蔽冲突。

<script type="text/javascript">
jquery.noconflict();  //将变量$的控制权让渡给prototype.js
(function($){   //定义匿名函数并设置形参为$
 $(function(){   //匿名函数内部的$均为jquery
 $("p").click(function(){ //继续使用 $ 方法
  alert($(this).text());
 });
 });
})(jquery);    //执行匿名函数且传递实参jquery

$("pp").style.display = 'none'; //使用prototype
</script>

3、jquery库在其他库之前导入

jquery库在其他库之前导入,$的归属权默认归后面的javascript库所有。那么可以直接使用"jquery"来做一些jquery的工作。

同时,可以使用$()方法作为其他库的快捷方式。这里无须调用jquery.noconflict()函数。

<!-- 引入 jquery -->
<script src="../../scripts/jquery.js" type="text/javascript"></script>
<!-- 引入 prototype -->
<script src="lib/prototype.js" type="text/javascript"></script>

<body>
<p id="pp">test-prototype(将被隐藏)</p>
<p >test-jquery(将被绑定单击事件)</p>

<script type="text/javascript">
jquery(function(){ //直接使用 jquery ,没有必要调用"jquery.noconflict()"函数。
 jquery("p").click(function(){  
  alert( jquery(this).text() );
 });
});

$("pp").style.display = 'none'; //使用prototype
</script>
</body>

二、原理

1、源码

源码:看一下源码里怎么做到的

var
// map over jquery in case of overwrite
_jquery = window.jquery,

// map over the $ in case of overwrite
_$ = window.$,

jquery.extend({
 noconflict: function( deep ) {
   if ( window.$ === jquery ) {
    window.$ = _$;
   }

   if ( deep && window.jquery === jquery ) {
    window.jquery = _jquery;
   }

   return jquery;
  }
});

在jquery加载的时候,通过事先声明的_jquery变量获取到当前window.jquery,通过_$获取到当前window.$

通过jquery.extend()把noconflict挂载到jquery下面。所以我们在调用的时候都是jquery.noconflict()这样调。

在调用noconflict()时做了2个判断,

第一个if,把$的控制权交出去。

第二个if,在noconflict()传参的时候把,jquery的控制权交出去。

最后noconflict()返回jquery对象,用哪个参数接收,哪个参数将拥有jquery的控制权。

2、 验证

//冲突 
 var $ = 123; //假设其他库中$为123
 $(
   function () {
    console.log($); //报错uncaught typeerror: $ is not a function
   }
 );

解决冲突

//解决冲突
 var jq = $.noconflict();
 var $ = 123;
 jq(function () {
  alert($); //123
 });

释放$控制权例子

<script>
 var $ = 123; // window.$是123,存储在私有的_$上。

</script>
<script src="https://code.jquery.com/jquery-2.2.4.js"></script>
<body>
<div>aaa</div>
<script>
 var jq = $.noconflict();//当window.$===jquery的时候,把_$赋给了window.$。
 jq(function () {
  alert($); //123
 });
</script>

释放jquery控制权例子

参数deep的作用:deep用来放弃jquery对外的接口。

 如下,noconflict()不写参数,弹出jquery为构造函数。

<script>
 var $ = 123;
 var jquery=456;
</script>
<script src="https://code.jquery.com/jquery-2.0.3.js"></script>
<body>
<div>aaa</div>
<script>
 var jq = $.noconflict();
 jq(function () {
  alert(jquery); //构造函数
 });
</script>

关于jQuery库冲突的完美解决办法

如果写个参数true,会弹出456。

<script>
 var $ = 123;
 var jquery=456;
</script>
<script src="https://code.jquery.com/jquery-2.0.3.js"></script>
<body>
<div>aaa</div>
<script>
 var jq = $.noconflict(true); //写了true或者参数的时候,deep为真window.jquery===jquery为真,所以进入if条件。把456赋值给window.jquery
 jq(function () {
  alert(jquery); //456
 });
</script>

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对的支持。