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


Posted in jQuery onMay 20, 2017

前言

一次面试中面试官问到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>

总结

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

jQuery 相关文章推荐
bootstrap+jQuery 实现下拉菜单中复选框全选和全不选效果
Jun 12 jQuery
jQuery图片缩放插件smartZoom使用实例详解
Aug 25 jQuery
jQuery实现用户信息表格的添加和删除功能
Sep 12 jQuery
jquery自定义显示消息数量
Dec 19 jQuery
jQuery中ajax获取数据赋值给页面的实例
Dec 31 jQuery
实现jquery放大镜的两种方法
Feb 22 jQuery
jQuery实现获取及设置CSS样式操作详解
Sep 05 jQuery
jQuery实现侧边栏隐藏与显示的方法详解
Dec 22 jQuery
Jquery 动态添加元素并添加点击事件实现过程解析
Oct 12 jQuery
JQuery发送ajax请求时中文乱码问题解决
Nov 14 jQuery
Jquery Fade用法详解
Nov 06 jQuery
jQuery实现鼠标拖动图片功能
Mar 04 jQuery
jquery.guide.js新版上线操作向导镂空提示jQuery插件(推荐)
May 20 #jQuery
JS jQuery使用正则表达式去空字符的简单实现代码
May 20 #jQuery
jQuery插件select2利用ajax高效查询大数据列表(可搜索、可分页)
May 19 #jQuery
jQuery操作之效果详解
May 19 #jQuery
jQuery Validate 校验多个相同name的方法
May 18 #jQuery
jQuery Validate 无法验证 chosen-select元素的解决方法
May 17 #jQuery
jQuery查找dom的几种方法效率详解
May 17 #jQuery
You might like
水质对咖图啡风味的影响具体有哪些
2021/03/03 冲泡冲煮
把从SQL中取出的数据转化成XMl格式
2006/10/09 PHP
UTF8编码内的繁简转换的PHP类
2009/07/09 PHP
php删除与复制文件夹及其文件夹下所有文件的实现代码
2013/01/23 PHP
php删除数组元素示例分享
2014/02/17 PHP
php实现获取及设置用户访问页面语言类
2014/09/24 PHP
php实现mysql数据库分表分段备份
2015/06/18 PHP
PHP getallheaders无法获取自定义头(headers)的问题
2016/03/23 PHP
php构造函数与析构函数
2016/04/23 PHP
基于PHP实现的多元线性回归模拟曲线算法
2018/01/30 PHP
PHP children()函数讲解
2019/02/03 PHP
Jquery replace 字符替换实现代码
2010/12/02 Javascript
js内存泄露的几种情况详细探讨
2013/05/31 Javascript
jQuery的cookie插件实现保存用户登陆信息
2014/04/15 Javascript
使用script的src实现跨域和类似ajax效果
2014/11/10 Javascript
纯js实现无限空间大小的本地存储
2015/06/18 Javascript
JavaScript实现同一页面内两个表单互相传值的方法
2015/08/12 Javascript
js实现的简洁网页滑动tab菜单效果代码
2015/08/24 Javascript
jQuery插件实现无缝滚动特效
2015/11/24 Javascript
一些实用性较高的js方法
2016/04/19 Javascript
BootStrap table删除指定行的注意事项(笔记整理)
2017/02/05 Javascript
原生js封装自定义滚动条
2017/03/24 Javascript
Angular4实现动态添加删除表单输入框功能
2017/08/11 Javascript
D3.js的基础部分之数组的处理数组的排序和求值(v3版本)
2019/05/09 Javascript
深入浅析ImageMagick命令执行漏洞
2016/10/11 Python
解决python3读取Python2存储的pickle文件问题
2018/10/25 Python
python 利用matplotlib在3D空间绘制二次抛物面的案例
2021/02/06 Python
简单介绍HTML5中audio标签的使用
2015/09/24 HTML / CSS
Prototype是怎么扩展DOM的
2014/10/01 面试题
会计系个人求职信范文分享
2013/12/20 职场文书
人力资源部副职的竞聘演讲稿
2014/01/07 职场文书
将相和教学反思
2014/02/04 职场文书
离职感谢信怎么写
2015/01/22 职场文书
党员反邪教心得体会
2016/01/15 职场文书
2019年冬至:天冷暖人心的问候祝福语大全
2019/12/20 职场文书
Nginx+Tomcat实现负载均衡、动静分离的原理解析
2021/03/31 Servers