三分钟带你玩转jQuery.noConflict()

jQuery是目前使用最广泛的前端框架之一,有大量的第三方库和插件基于它开发。为了避免全局命名空间污染,jQuery提供了jQuery.noConflict()方法解决变量冲突。这个方法,毫无疑问,非常有效。遗憾的是,jQuery的官方文档对该方法的描述不够清晰,许多开发者并不清楚当他们调用jQuery.noConflict()时,究竟发生了什么,从而导致在使用时出现了许多问题。尽管如此,jQuery.noConflict()背后实现原理依然值得Web开发者学习掌握,成为解决类似全局命名空间污染问题的利器。

jQuery.noConflict()的作用?

  jQuery.noConflict()的存在只有一个目的:它允许你在同一个页面加载多个jQuery实例,尤其是不同版本的jQuery。你可能会觉得奇怪,为什么要在一个页面加载/使用多个不同版本的jQuery对象呢?一般而言,有两种情况。第一种情况,你的业务代码采用了最新版的jQuery库,而你选用的第三方插件依赖的更早版本的jQuery库;第二种情况,你正维护着一个系统,它已有的业务代码由于各种原因,引用了较老版本的jQuery库,你新开发的模块采用的是其他版本的jQuery库。不论哪种情况,你都不得不面对,jQuery对象/方法冲突的问题。幸运的是,jQuery.noConflict()帮你解决了这个烦恼。

jQuery被加载时发生了什么?

当jQuery被页面引用/加载时,它被封装在一个自执行函数(匿名函数)里,它提供的所有一切变量、函数、对象都在匿名函数内部的可执行环境内,外部环境无法调用,以防止全局命名空间污染。

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script> 

jQuery在匿名函数内部定义了两个全局对象:jQuery和$,把自己暴露给外部环境。开发者习惯使用的各种公共方法都是通过这两个对象进行访问的,如jQuery.ajax(),jQuery.css()等。在最初,它们指向匿名函数内部的同一个对象jQuery(私有变量),通过它访问匿名函数内部的私有变量和函数。这使得匿名函数在自执行后其内部的私有变量和函数仍然进驻在内存里,不会被javascript的垃圾回收机制清除。

window.jQuery = window.$ = jQuery; 

当jQuery被页面加载后,当前页面有可能已经存在了jQuery和$这两个全局变量(比如,加载了其它的第三方库,其内部也定义了它俩),这就会导致已经存在的对象被覆盖(全局命名空间污染)。为了解决这个问题,jQuery在内部先将已经存在的全局变量缓存起来,保存在私有变量_jQuery和_$中,供后续调用。所以,如果页面在加载jQuery库时,还不存在jQuery和$对象,那么_jQuery和_$都是undefined;否则,它们都会保存对已有jQuery和$的引用(也许来自之前引用的第三方库或是不同版本的jQuery库)。之后,jQuery会像上文说描述的那样,覆盖这两个全局变量并将自己暴露给外部环境。至此,页面上的全局变量jQuery和$已经指向刚刚引入的jQuery库。

// Map over jQuery in case of overwrite
_jQuery = window.jQuery,
// Map over the $ in case of overwrite
_$ = window.$,
// Otherwise expose jQuery to the global object as usual
window.jQuery = window.$ = jQuery; 

jQuery.noConflict()的神奇效果?

假设你维护的系统已经引用了1.7.0版本的jQuery库,而你在新添加的功能里引用了1.10.2版本的jQuery库。那么,还有办法重新使用jQuery 1.7.0 或是同时使用两个版本的jQuery库吗?答案是肯定,那就是jQuery.noConflict()。实际上,利用jQuery.noConflict(),你可以立刻把全局变量jQuery和$重新指向之前引用的对象。很神奇吧?这就是为什么jQuery在对外暴露自己前内部缓存了之前引用的对象。

  jQuery.noConflict()接受一个可选的布尔值参数,通常默认值是false。这个参数会带来什么影响呢?其实,很简单。如果调用jQuery.noConflict()或是jQuery.noConflict(false),只有全局变量$会被重置恢复成之前的引用值;如果调用jQuery.noConflict()或是jQuery.noConflict(true),那么全局变量jQuery和$都会被重置恢复成之前的引用值。这一点非常重要,建议牢记。当你调用jQuery.noConflict(false/true)之后,它会返回当前jQuery的实例,利用这个特性我们可以实现jQuery的重命名。

// "Renaming" jQuery
var jayquery = jQuery.noConflict( true );
// Now we can call things like jayquery.ajax(), jayquery.css(), and so on

我们再来看一个代码片段,测试一下是否真正理解了神奇的noConflict()

<!-- jQuery and $ are undefined -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<!-- jQuery and $ now point to jQuery 1.10.2 -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.0/jquery.min.js">
<!-- jQuery and $ now point to jQuery 1.7.0 -->
<script>jQuery.noConflict();</script>
<!-- jQuery still points to jQuery 1.7.0; $ now points to jQuery 1.10.2 -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js">
<!-- jQuery and $ now point to jQuery 1.6.4 -->
<script>var jquery164 = jQuery.noConflict( true );</script>
<!-- jQuery now points to jQuery 1.7.0; $ now points to jQuery 1.10.2; jquery164 points to jQuery 1.6.4 --> 

避免第三方库的冲突

以上的代码片段展示了如何解决多版本jQuery的冲突。接下来,我们尝试解决jQuery库和第三方库的冲突,下面出现的代码片段在jQuery的官方文档中都有,有兴趣的程序猿可以仔细阅读官方文档体会其中的区别。

直接使用No-Conflict模式

使用No-Conflict模式,其实就是对jQuery进行重命名,再调用。

<!-- 采用no-conflict模式,jquery.js在prototype.js之后被引入. -->
<script src="prototype.js"></script>
<script src="jquery.js"></script>
<script>
var $j = jQuery.noConflict();
// $j 引用了jQuery对象本身.
$j(document).ready(function() {
$j( "div" ).hide();
});
// $ 被重新指向prototype.js里定义的对象
// document.getElementById(). mainDiv below is a DOM element, not a jQuery object.
window.onload = function() {
var mainDiv = $( "main" );
}
</script> 

使用自执行函数封装

使用这种方式,你可以在匿名函数内部继续使用标准的$对象,这也是众多jQuery插件采用的方法。需要注意的是,使用这种方法,函数内部无法再使用prototype.js定义的$对象了。

<!-- jquery.js在prototype.js之后被引入. -->
<script src="prototype.js"></script>
<script src="jquery.js"></script>
<script>
jQuery.noConflict();
(function( $ ) {
// Your jQuery code here, using the $
})( jQuery );
</script> 

使用标准jQuery(document).ready()函数

如果jQuery库在其它库之前引入,那么jQuery内部定义的jQuery和$会被第三方库覆盖,这时候再使用noConflict()已经没有什么意义了。解决的方法很简单,直接使用jQuery的标准调用方式。

<!-- jquery.js在prototype.js之前被引入. -->
<script src="jquery.js"></script>
<script src="prototype.js"></script>
<script>
// Use full jQuery function name to reference jQuery.
jQuery( document ).ready(function() {
jQuery( "div" ).hide();
});
// 或者
jQuery(function($){
// Your jQuery code here, using the $
});
// Use the $ variable as defined in prototype.js
window.onload = function() {
var mainDiv = $( "main" );
};
</script>

下面给大家介绍jQuery noConflict() 方法

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

实例

当然,您仍然可以通过全名替代简写的方式来使用 jQuery:

$.noConflict();
jQuery(document).ready(function(){
jQuery("button").click(function(){
jQuery("p").text("jQuery 仍在运行!");
});
});

实例

您也可以创建自己的简写。noConflict() 可返回对 jQuery 的引用,您可以把它存入变量,以供稍后使用。请看这个例子:

var jq = $.noConflict();
jq(document).ready(function(){
jq("button").click(function(){
jq("p").text("jQuery 仍在运行!");
});
});

实例

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

$.noConflict();
jQuery(document).ready(function($){
$("button").click(function(){
$("p").text("jQuery 仍在运行!");
});
});
(0)

相关推荐

  • jQuery中 noConflict() 方法使用

    jQuery 和其他 JavaScript 框架正如您已经了解到的,jQuery 使用 $ 符号作为 jQuery 的简写. 如果其他 JavaScript 框架也使用 $ 符号作为简写怎么办? 其他一些 JavaScript 框架包括:MooTools.Backbone.Sammy.Cappuccino.Knockout.JavaScript MVC.Google Web Toolkit.Google Closure.Ember.Batman 以及 Ext JS. 其中某些框架也使用 $ 符号

  • jQuery用noConflict代替$的实现方法

    js框架很多的情况下,很容易出现冲突,建议使用noConflict代替$ //消除$对jquery缩写 $.noConflict(); //使用了noConflict后,用$就会无效,应用jQuery jQuery(document).ready(function(){ console.log("sdf"); }) 也可以指定新的代替jQuery的名称 var myjq=$.noConflict(); myjq(document).ready(function(){ console.l

  • 避免jQuery名字冲突 noConflict()方法

    众所周知,在jQuery语法中,$符号是jQuery的简写方式.但在某些情况下,可能需要在同一个页面引入其他javascript库(比如Prototype).因为$简短方便,很多的库也是使用$符号.为了避免名称冲突,jQuery提供了noConflict()方法来解决这个问题.调用该方法可以把对$标识符的控制权让给其他库. 一般模式: <script src="prototype.js"></script>//1.包含jQuery之外的库(比如Prototype

  • jQuery中noconflict函数的实现原理分解

    jQuery中,noconflict是用来防止变量冲突,用来释放变量控制权的一个重要方法.我们知道,jQuery中对外提供有两个全局变量,$和jQuery,虽然jQuery只产生了两个全局变量,极少情况下才会出现冲突,但是如果网页中如果包涵较多的类库,有自定义$或jQuery全局变量的存在时,就产生冲突. jQuery提供的noconflict函数很好的解决了变量冲突问题,无论是$或者jQuery冲突都可以解决,接下来我们就来分析一下jQuery的冲突处理. 先来看一下jQuery源码中noco

  • 轻松搞定jQuery.noConflict()

    jQuery是目前使用最广泛的前端框架之一,有大量的第三方库和插件基于它开发.为了避免全局命名空间污染,jQuery提供了jQuery.noConflict()方法解决变量冲突.这个方法,毫无疑问,非常有效.遗憾的是,jQuery的官方文档对该方法的描述不够清晰,许多开发者并不清楚当他们调用jQuery.noConflict()时,究竟发生了什么,从而导致在使用时出现了许多问题.尽管如此,jQuery.noConflict()背后实现原理依然值得Web开发者学习掌握,成为解决类似全局命名空间污染

  • jquery插件冲突(jquery.noconflict)解决方法分享

    许多的 JS 框架类库都选择使用$符号作为函数或变量名,jQuery是其中最为典型的一个.在 jQuery 中,$ 符号只是 window.jQuery 对象的一个引用,因此即使 $ 被删除,window.jQuery 依然是保证整个类库完整性的坚强后盾.jQuery 的 API 设计充分考虑了多框架之间的引用冲突,我们可以使用 jQuery.noConflict 方法来轻松实现控制权的移交. jQuery.noConflict 方法包含一个可选的布尔参数[1],用以决定移交 $ 引用的同时是否

  • jQuery中noConflict()用法实例分析

    本文实例讲述了jQuery中noConflict()用法.分享给大家供大家参考.具体分析如下: jQuery默认使用"$"操作符,$ 符号只是 window.jQuery 对象的一个引用,jQuery.noConflict() ,这个函数将变量$的控制权让渡给第一个实现它的那个库.这有助于确保jQuery不会与其他库的$对象发生冲突.在运行这个函数后,就只能使用jQuery变量访问jQuery对象.例如,在要用到$("div p")的地方,就必须换成jQuery(&

  • 『jQuery』名称冲突使用noConflict方法解决

    jQuery 使用 $ 符号作为 jQuery 的简介方式. 某些其他 JavaScript 库中的函数(比如 Prototype)同样使用 $ 符号. jQuery 使用名为 noConflict() 的方法来解决该问题. var jq=jQuery.noConflict(),帮助使用自己的名称(比如 jq)来代替 $ 符号. 复制代码 代码如下: <html> <head> <script type="text/javascript" src=&quo

  • 三分钟带你玩转jQuery.noConflict()

    jQuery是目前使用最广泛的前端框架之一,有大量的第三方库和插件基于它开发.为了避免全局命名空间污染,jQuery提供了jQuery.noConflict()方法解决变量冲突.这个方法,毫无疑问,非常有效.遗憾的是,jQuery的官方文档对该方法的描述不够清晰,许多开发者并不清楚当他们调用jQuery.noConflict()时,究竟发生了什么,从而导致在使用时出现了许多问题.尽管如此,jQuery.noConflict()背后实现原理依然值得Web开发者学习掌握,成为解决类似全局命名空间污染

  • 三分钟带你了解SpringBoot真正的启动引导类

    引言 SpringBoot项目中的启动类,一般都是XXApplication,例如**「StatsApplication」,「UnionApplication」**. 每个项目的启动类名称都不一样.但是它的启动类真的是XXApplication吗? **META-INF/**Manifest.mf文件 jar文件实际上是class文件的zip压缩存档.jar并不能表达应用程序的便签信息. 「META-INF/Manifest.mf文件提供存档的便签信息.」 Manifest.mf有 「Main-

  • 三分钟带你快速学会微信小程序的条件渲染

    目录 前言 1.wx:if实现条件渲染 2.block结合wx:if使用 3.hiden实现条件渲染 4. wx:if vs hidden 补充:hidden 和 wx:if 的区别 总结 前言 这篇文章是三分钟学会小程序的条件渲染教程,所谓的条件渲染就是判断是否需要把代码渲染到展示页面上.使用以下三种方式可以实现条件渲染,各自有不同的应用场景,只有熟练掌握其用法,在使用时才能得心应手. 1.wx:if实现条件渲染 在框架中,使用 wx:if="" 来判断是否需要渲染该代码块: <

  • [图文]三分钟学会Sql Server的复制功能

    根据网络情况,可能达到10秒左右的延时,即主数据库添加,删除,更新的内容,一般在10秒内就可以同步到备用数据库上. 三分钟的视频操作演示在最下面,不要忘记看了. 1.配置分布发服务器 2.新建发布 3.这里介绍事务发布 4.选择要发布的表,注意:只有带主键的表才可以发布 5.这是个问题,因为很多表中,我们会有这个自动编号的功能,不过你可以自己修改存储过程来实现这个功能. 加上用到 SET IDENTITY_INSERT xxxtable ON的功能 6.发布建好后,我们有强制新订阅来发布,如果要

  • 30分钟带你了解Docker(推荐)

    最近一直在忙项目,不知不觉2个多月没有更新博客了.正好自学了几天docker就干脆总结一下,也顺带增加一篇<30分钟入门系列>.网上能够查到的对于docker的定义我就不再重复了,说说我自己对它的理解:Docker一个方便多次部署的虚拟化Linux容器,与当下流行的SpringBoot和微服务框架搭配更加相得益彰,从而真正的做到从开发到部署的全流程灵敏.请注意这里的三个关键词:Linux容器,SpringBoot,灵敏.首先,Docker不能别用来部署本地应用(如果你有开发过基于Qt的桌面应用

  • 五分钟带你搞懂python 迭代器与生成器

    前言 大家周末好,今天给大家带来的是Python当中生成器和迭代器的使用. 我当初第一次学到迭代器和生成器的时候,并没有太在意,只是觉得这是一种新的获取数据的方法.对于获取数据的方法而言,我们会一种就足够了.但是在我后来Python的使用以及TensorFlow等学习使用当中,我发现很多地方都用到了迭代器和生成器,或者是直接使用,或者是借鉴了思路.今天就让我们仔细来看看,它们到底是怎么回事. 迭代器 我们先从迭代器开始入手,迭代器并不是Python独有的概念,在C++和Java当中都有itera

  • 五分钟带你了解Java的接口数据校验

    本篇文章给大家分享平时开发中总结的一点小技巧!在工作中写过Java程序的朋友都知道,目前使用Java开发服务最主流的方式就是通过Spring MVC定义一个Controller层接口,并将接口请求或返回参数分别定义在一个Java实体类中,这样Spring MVC在接收到Http请求(POST/GET)后,就会自动将请求报文自动映射成一个Java对象.这样的代码通常是这样写的: @RestController public class OrderController { @Autowired pr

  • 一篇文章让你三分钟学会Java枚举

    什么是枚举 至于枚举,我们先拿生活中的枚举来入手,然后再引申Java中的枚举,其实它们的意义很相似. 谈到生活中的枚举,假如我们在玩掷骰子的游戏,在我们手中有两个骰子,要求掷出两个骰子的点数和必须大于6的概率,那么在此情此景,我们就需要使用枚举法一一列举出骰子点数的所有可能,然后根据列举出来的可能,求出概率. 可能有的小伙伴发现,这就是数学啊?这就是数学中的概率学和统计学.对,我们的枚举法就是常用于概率统计中的. 枚举类enum是jdk1.5引入的,全称enumeration,和class.in

  • 详解三分钟快速搭建分布式高可用的Redis集群

    这里的Redis集群指的是Redis Cluster,它是Redis在3.0版本正式推出的专用集群方案,有效地解决了Redis分布式方面的需求.当单机内存.并发.流量等遇到瓶颈的时候,可以采用这种Redis Cluster方案进行解决. 分区规则 Redis Cluster采用虚拟槽(slot)进行数据分区,即使用分散度良好的哈希函数把所有键映射到一个固定范围的整数集合里,这里的整数就是槽(slot).Redis Cluster槽的范围是0~16383,计算公式:slot=CRC16(key)

随机推荐