关于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 相关文章推荐
jQuery插件FusionCharts绘制ScrollColumn2D图效果示例【附demo源码下载】
Mar 22 jQuery
jQuery实现简单的手风琴效果
Apr 17 jQuery
jQuery实现一个简单的验证码功能
Jun 26 jQuery
jQuery Form插件使用详解_动力节点Java学院整理
Jul 17 jQuery
jQuery实现手势解锁密码特效
Aug 14 jQuery
JavaScript实现离开页面前提示功能【附jQuery实现方法】
Sep 26 jQuery
jQuery插件artDialog.js使用与关闭方法示例
Oct 09 jQuery
关于jquery中attr()和prop()方法的区别
May 28 jQuery
jQuery实现的点击按钮改变样式功能示例
Jul 21 jQuery
jquery绑定事件 bind和on的用法与区别分析
May 22 jQuery
JQuery基于FormData异步提交数据文件
Sep 01 jQuery
JavaScript枚举选择jquery插件代码实例
Nov 17 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
使用sockets:从新闻组中获取文章(一)
2006/10/09 PHP
phpmyadmin安装时提示:Warning: require_once(./libraries/common.inc.php)错误解决办法
2011/08/18 PHP
解析posix与perl标准的正则表达式区别
2013/06/17 PHP
php采用curl模仿登录人人网发布动态的方法
2014/11/07 PHP
PHP原生函数一定好吗?
2014/12/08 PHP
pjblog修改技巧汇总
2007/03/12 Javascript
JavaScript 函数惰性载入的实现及其优点介绍
2013/08/12 Javascript
详解JavaScript中循环控制语句的用法
2015/06/03 Javascript
Bootstrap实现带暂停功能的轮播组件(推荐)
2016/11/25 Javascript
jquery UI Datepicker时间控件冲突问题解决
2016/12/16 Javascript
详解AngularJS 路由 resolve用法
2017/04/24 Javascript
JS和jQuery通过this获取html标签中的属性值(实例代码)
2017/09/11 jQuery
JQuery Ajax动态加载Table数据的实例讲解
2018/08/09 jQuery
Vue.js 图标选择组件实践详解
2018/12/03 Javascript
基于node简单实现RSA加解密的方法步骤
2019/03/21 Javascript
vue中使用elementUI组件手动上传图片功能
2019/12/13 Javascript
bootstrap实现嵌套模态框的实例代码
2020/01/10 Javascript
浅谈Vue3.0新版API之composition-api入坑指南
2020/04/30 Javascript
js实现验证码干扰(静态)
2021/02/22 Javascript
[01:48:04]DOTA2-DPC中国联赛 正赛 PSG.LGD vs Elephant BO3 第一场 2月7日
2021/03/11 DOTA
python创建和使用字典实例详解
2013/11/01 Python
Python实现多条件筛选目标数据功能【测试可用】
2018/06/13 Python
django 发送邮件和缓存的实现代码
2018/07/18 Python
Python如何优雅删除字符列表空字符及None元素
2020/06/25 Python
python中加背景音乐如何操作
2020/07/19 Python
python3中数组逆序输出方法
2020/12/01 Python
Myprotein荷兰官网:欧洲第一运动营养品牌
2020/07/11 全球购物
军训的自我鉴定
2013/12/10 职场文书
大学生职业生涯规划范文
2014/01/08 职场文书
教师专业自荐信
2014/05/31 职场文书
国际贸易本科毕业生求职信
2014/09/26 职场文书
医院领导班子整改方案
2014/10/01 职场文书
兴趣班停课通知
2015/04/24 职场文书
大学生创业,为什么都会选择快餐饮?
2019/08/08 职场文书
mysql主从复制的实现步骤
2021/10/24 MySQL
云服务器部署 Web 项目的实现步骤
2022/06/28 Servers