Three minutes to get you going

  • 2020-12-19 20:53:35
  • OfStack

jQuery is one of the most widely used front-end frameworks today, and a large number of third side libraries and plug-ins are developed based on it. To avoid global namespace pollution, jQuery provides the jQuery.noConflict () method to resolve variable conflicts. This method, no doubt, is very effective. Unfortunately, the official documentation for jQuery does not describe this method clearly enough, and many developers do not know exactly what happens when they call jQuery.noConflict (), leading to many problems in use. Still, the principles behind jQuery.noConflict () are worth learning for Web developers as a useful tool for solving similar global namespace pollution problems.

jQuery. The role of noConflict()?

The & # 8195; The & # 8195; jQuery. noConflict() exists for one purpose only: it allows you to load multiple instances of jQuery on the same page, especially different versions of jQuery. You may wonder why you would want to load/use multiple versions of jQuery objects in one page. Generally speaking, there are two cases. In the first case, your business code uses the latest version of the jQuery library, while your third party plug-in relies on an earlier version of the jQuery library. In the second case, you are maintaining a system whose existing business code references an older version of the jQuery library for a variety of reasons, and your newly developed module uses another version of the jQuery library. In either case, you have to deal with the problem of jQuery object/method conflicts. Luckily, ES31en.noConflict () helps you out.

What happens when jQuery is loaded?

When jQuery is referenced/loaded by the page, it is encapsulated in a self-executing function (anonymous function). All the 1-cut variables, functions, and objects it provides are in the executable environment inside the anonymous function and cannot be called by the external environment to prevent global namespace pollution.


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

jQuery defines two global objects within the anonymous function, jQuery and $, to expose itself to the external environment. Various public methods that developers are accustomed to using, such as jQuery.ajax (), jQuery.css (), are accessed through these two objects. Initially, they point to the same object inside the anonymous function, jQuery(private variable), through which private variables and functions inside the anonymous function are accessed. This allows anonymous functions to keep their internal private variables and functions in memory after execution and not be cleaned up by javascript's garbage collection mechanism.


window.jQuery = window.$ = jQuery; 

When jQuery is loaded by the page, it is possible that the current page already has two global variables, jQuery and $(for example, another third library is loaded, and both are defined internally), which causes the existing objects to be overwritten (global namespace pollution). To solve this problem, jQuery internally first caches the existing global variables and stores them in the private variables _jQuery and _$for subsequent calls. So, if the jQuery and $objects don't exist when the page loads the jQuery library, then _jQuery and _$are both undefined; Otherwise, they all hold references to existing jQuery and $(perhaps from a previously referenced third repository or a different version of the jQuery library). jQuery then overrides these two global variables and exposes itself to the external environment, as described above. At this point, the global variables jQuery and $on the page point to the jQuery library that you just introduced.


// 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. The magic of noConflict()?

Assume that the system you maintain already references the 1.7.0 version of the jQuery library, and that you refer to the 1.10.2 version of the jQuery library in the new additions. So, is there a way to reuse jQuery 1.7.0 or use both versions of the jQuery library? The answer is yes, jQuery.noConflict (). In fact, with jQuery.noConflict (), you can immediately redirect the global variables jQuery and $to the previously referenced object. Isn't that amazing? This is why jQuery internally caches previously referenced objects before exposing itself externally.

The & # 8195; The & # 8195; jQuery.noConflict() takes an optional Boolean parameter, and is usually false by default. What is the effect of this parameter? Actually, it's very simple. If you call jQuery.noConflict () or jQuery.noConflict (false), only the global variable $will be reset to its previous reference value. If you call jQuery.noConflict () or jQuery.noConflict (true), the global variables jQuery and $are reset to their previous reference values. This is a very important point to keep in mind. When you call ES105en.noConflict (false/true), it returns an instance of the current jQuery. This feature allows you to rename jQuery.


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

Let's look at one more code snippet to test if we really understand the magic of noConflict()


<!-- jQuery and $ are undefined -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<!-- jQuery and $ now point to jQuery 1.10.2 -->
<script src="//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="//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 --> 

Avoid conflicts with the third repository

The above code snippet shows how to resolve conflicts with multiple versions of jQuery. Next, we try to resolve the conflict between the jQuery library and the third library. The following code snippets are in the official jQuery documentation, which interested programmers can read carefully to see the difference.

Use No-ES130en mode directly

Using the ES134en-ES135en pattern, you are essentially renaming and calling jQuery.


<!--  using no-conflict Mode, jquery.js in prototype.js And then it was introduced . -->
<script src="prototype.js"></script>
<script src="jquery.js"></script>
<script>
var $j = jQuery.noConflict();
// $j  Refer to the jQuery The object itself .
$j(document).ready(function() {
$j( "div" ).hide();
});
// $  Redirected prototype.js Object defined in 
// document.getElementById(). mainDiv below is a DOM element, not a jQuery object.
window.onload = function() {
var mainDiv = $( "main" );
}
</script> 

Use self-executing function encapsulation

In this way, you can continue to use the standard $object inside anonymous functions, which is the approach adopted by many jQuery plug-ins. Note that with this approach, the $object defined by prototype.js can no longer be used internally within the function.


<!-- jquery.js in prototype.js And then it was introduced . -->
<script src="prototype.js"></script>
<script src="jquery.js"></script>
<script>
jQuery.noConflict();
(function( $ ) {
// Your jQuery code here, using the $
})( jQuery );
</script> 

Use the standard jQuery(document).ready () function

If the jQuery library is introduced before other libraries, then the jQuery and $defined internally by jQuery will be overwritten by the third library, and there is no point in using noConflict() again. The solution is simple, using jQuery's standard invocation style.


<!-- jquery.js in prototype.js Was introduced before . -->
<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();
});
//  or 
jQuery(function($){
// Your jQuery code here, using the $
});
// Use the $ variable as defined in prototype.js
window.onload = function() {
var mainDiv = $( "main" );
};
</script>

Here is the jQuery noConflict() method

The noConflict() method releases control of the $identifier so that other scripts can use it.

The instance

Of course, you can still use jQuery by using your full name instead of the abbreviation:


$.noConflict();
jQuery(document).ready(function(){
jQuery("button").click(function(){
jQuery("p").text("jQuery  Still running! ");
});
});

The instance

You can also create your own abbreviations. noConflict() returns a reference to jQuery, which you can store in a variable for later use. Here's an example:


var jq = $.noConflict();
jq(document).ready(function(){
jq("button").click(function(){
jq("p").text("jQuery  Still running! ");
});
});

The instance

If your jQuery code block uses the $shorthand and you don't want to change the shortcut, you can pass the $symbol as a variable to the ready method. This allows you to use the $symbol inside the function - but outside the function, you still have to use "jQuery" :


window.jQuery = window.$ = jQuery; 
0

Related articles: