关于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实现键盘回车搜索功能
Jul 25 jQuery
浅谈ajax在jquery中的请求和servlet中的响应
Jan 22 jQuery
jQuery实现的回车触发按钮事件功能示例
Mar 25 jQuery
jquery.onoff实现简单的开关按钮功能(推荐)
May 24 jQuery
jQuery实现导航样式布局操作示例【可自定义样式布局】
Jul 24 jQuery
详解jQuery-each()方法
Mar 13 jQuery
jQuery 选择器用法基础入门示例
Jan 04 jQuery
jQuery插件simplePagination的使用方法示例
Apr 28 jQuery
jQuery实现的移动端图片缩放功能组件示例
May 01 jQuery
jQuery HTML获取内容和属性操作实例分析
May 20 jQuery
基于JQuery和DWR实现异步数据传递
Oct 16 jQuery
jQuery实现全选按钮
Jan 01 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 应用程序的安全 -- 不能违反的四条安全规则
2006/11/26 PHP
php中的字符编码转换函数用法示例
2014/10/20 PHP
php编写批量生成不重复的卡号密码代码
2015/05/14 PHP
PHP使用星号隐藏用户名,手机和邮箱的实现方法
2016/09/22 PHP
thinkphp集成前端脚手架Vue-cli的教程图解
2018/08/30 PHP
jQuery EasyUI API 中文文档 - ComboTree组合树
2011/10/11 Javascript
深入理解JavaScript系列(4) 立即调用的函数表达式
2012/01/15 Javascript
javascript操作JSON的要领总结
2012/12/09 Javascript
jquery和雅虎的yql服务实现天气预报服务示例
2014/02/08 Javascript
浅谈setTimeout 与 setInterval
2015/06/23 Javascript
JavaScript获取对象在页面中位置坐标的方法
2016/02/03 Javascript
JavaScript获取服务器端时间的方法
2016/11/29 Javascript
vue.js 底部导航栏 一级路由显示 子路由不显示的解决方法
2018/03/09 Javascript
Webpack中publicPath路径问题详解
2018/05/03 Javascript
vue实现动态显示与隐藏底部导航的方法分析
2019/02/11 Javascript
Vue框架下引入ActiveX控件的问题解决
2019/03/25 Javascript
vue+eslint+vscode配置教程
2019/08/09 Javascript
Vue的Options用法说明
2020/08/14 Javascript
python中__slots__用法实例
2015/06/04 Python
在Django的form中使用CSS进行设计的方法
2015/07/18 Python
简单谈谈python的反射机制
2016/06/28 Python
Python单体模式的几种常见实现方法详解
2017/07/28 Python
Python cookbook(数据结构与算法)对切片命名清除索引的方法
2018/03/13 Python
Python实现找出数组中第2大数字的方法示例
2018/03/26 Python
Python3.5文件读与写操作经典实例详解
2019/05/01 Python
python3.6中@property装饰器的使用方法示例
2019/08/17 Python
Python爬取你好李焕英豆瓣短评生成词云的示例代码
2021/02/24 Python
html5指南-3.如何实现html元素拖拽功能
2013/01/07 HTML / CSS
AC Lens:购买隐形眼镜
2017/02/26 全球购物
后勤服务中心总经理工作职责
2014/03/03 职场文书
经典安踏广告词
2014/03/21 职场文书
2014年电工工作总结
2014/11/20 职场文书
文员岗位职责
2015/02/04 职场文书
银行先进个人总结
2015/02/15 职场文书
文艺晚会开场白
2015/05/29 职场文书
Go语言中break label与goto label的区别
2021/04/28 Golang