关于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基于layui实现二级联动下拉选择(省份城市选择)
Jun 20 jQuery
jQuery实现html table行Tr的复制、删除、计算功能
Jul 10 jQuery
jQuery实现简单日期格式化功能示例
Sep 19 jQuery
jQuery中extend函数简单用法示例
Oct 11 jQuery
jquery点击回车键实现登录效果并默认焦点的方法
Mar 09 jQuery
jQuery实现文件编码成base64并通过AJAX上传的方法
Apr 12 jQuery
jquery 动态遍历select 赋值的实例
Sep 12 jQuery
jQuery实现为table表格动态添加或删除tr功能示例
Feb 19 jQuery
jQuery事件blur()方法的使用实例讲解
Mar 30 jQuery
jquery 遍历hash操作示例【基于ajax交互】
Oct 12 jQuery
JQuery获得内容和属性方法解析
May 30 jQuery
jQuery实现简单全选框
Sep 13 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
php简单日历函数
2015/10/28 PHP
学习ExtJS 访问容器对象
2009/10/07 Javascript
封装的原生javascript弹出层代码
2010/09/24 Javascript
兼容FF和IE的动态table示例自写
2013/10/21 Javascript
JavaScript之IE的fireEvent方法详细解析
2013/11/20 Javascript
javascript中AJAX用法实例分析
2015/01/30 Javascript
基于Jquery制作图片文字排版预览效果附源码下载
2015/11/18 Javascript
Vue filter介绍及其使用详解
2017/10/21 Javascript
JavaScript数组push方法使用注意事项
2017/10/30 Javascript
Angularjs Promise实例详解
2018/03/15 Javascript
vue addRoutes实现动态权限路由菜单的示例
2018/05/15 Javascript
一篇文章弄懂javascript中的执行栈与执行上下文
2019/08/09 Javascript
详解mpvue开发微信小程序基础知识
2019/09/23 Javascript
js实现简单点赞操作
2020/03/17 Javascript
Vue自定义render统一项目组弹框功能
2020/06/07 Javascript
Vue项目配置跨域访问和代理proxy设置方式
2020/09/08 Javascript
Python中logging模块的用法实例
2014/09/29 Python
Python中xrange与yield的用法实例分析
2017/12/26 Python
简单了解python的内存管理机制
2019/07/08 Python
详解python内置常用高阶函数(列出了5个常用的)
2020/02/21 Python
Django Xadmin多对多字段过滤实例
2020/04/07 Python
利用matplotlib为图片上添加触发事件进行交互
2020/04/23 Python
Pycharm安装Qt Design快捷工具的详细教程
2020/11/18 Python
Python排序函数的使用方法详解
2020/12/11 Python
纯css3实现宠物小鸡实例代码
2018/10/08 HTML / CSS
浅谈three.js中的needsUpdate的应用
2012/11/12 HTML / CSS
JAVA招聘远程笔试题
2015/07/23 面试题
这76道Java面试题及答案,祝你能成功通过面试
2016/04/16 面试题
年度考核自我评价
2014/01/25 职场文书
技能竞赛活动方案
2014/02/21 职场文书
党员公开承诺书范文
2014/03/25 职场文书
大学第二课堂活动总结
2014/07/08 职场文书
项目申请汇报材料
2014/08/16 职场文书
创先争优公开承诺书
2014/08/30 职场文书
大学学生个人总结
2015/02/15 职场文书
Spring Cloud Gateway去掉url前缀
2021/07/15 Java/Android