Here's the rub. Each group (app, skin, map) all want to use jQuery, but some want to use different versions. In fact, each group wants to control their own version of jQuery so that they are not effected if one group decides to update their copy of jQuery it does not effect the other group.
At first glance, this sounds reasonable... But... How to keep all versions of jQuery separated? When you initially load the jQuery javascript file, it calls an anonymous function:
(function( window, undefined ) { // Use the correct document accordingly with window argument (sandbox) var document = window.document, navigator = window.navigator, location = window.location; var jQuery = (function() { // Define a local copy of jQuery var jQuery = function( selector, context ) { // The jQuery object is actually just the init constructor 'enhanced' return new jQuery.fn.init( selector, context, rootjQuery ); }, // Map over jQuery in case of overwrite _jQuery = window.jQuery, // Map over the $ in case of overwrite _$ = window.$, ...
Because we are in an anonymous function, the jQuery library is constructed in a variable PRIVATE to the anonymous function. Besides this, let's look at a few more lines:
This existing window.jQuery & window.$ global variables are saved into private _jQuery and _$ variables. The reason for the window.$ save is that it is common for a JavaScript library to load and expose itself as window.$. The classic example typically given is the prototype library which also exposes itself as the window.$ variable. So, if we loaded prototype, then loaded jQuery, jQuery would overwrite the $ variable and prototype would no longer be available. However, by saving prototype (or whatever library is exposed by $), after we load jQuery, we can call the jQuery method .noConflict() which looks like this:
noConflict: function( deep ) { if ( window.$ === jQuery ) { window.$ = _$; } if ( deep && window.jQuery === jQuery ) { window.jQuery = _jQuery; } return jQuery; },
We have some interesting code here... Basically what happens is that when we call "noConflict()", the window.$ variable is restored back to its original state (prototype in our example). The second piece of the code looks at the "deep" Boolean parameter and optionally restores jQuery back to its original state. This was added a little later to the noConflict() method and was specifically added in the event that you have 2 different versions of jQuery being loaded. Let's look at the classic examples:
So here is that classic example for restoring the $ variable as given by the jQuery website:
http://docs.jquery.com/Using_jQuery_with_Other_Libraries
<html> <head> <script src="prototype.js"></script> <script src="jquery.js"></script> <script> jQuery.noConflict(); // Use jQuery via jQuery(...) jQuery(document).ready(function(){ jQuery("div").hide(); }); // Use Prototype with $(...), etc. $('someid').hide(); </script> </head> <body></body> </html>
And where you want to use different versions of jQuery (using the .noConflict(true) call), I could not find an "official" example... I did find a mention of it on:
http://api.jquery.com/jQuery.noConflict/
If necessary, we can free up the jQuery name as well by passing true as an argument to the method. This is rarely necessary, and if we must do this (for example, if we need to use multiple versions of the jQuery library on the same page), we need to consider that most plug-ins rely on the presence of the jQuery variable and may not operate correctly in this situation.And here is a good blog on the subject:
http://blog.nemikor.com/2009/10/03/using-multiple-versions-of-jquery/
With the example:
<!-- load jQuery 1.1.3 -->
<script type="text/javascript" src="http://code.jquery.com/jquery-1.1.3.js"></script>
<script type="text/javascript" src="jquery.dimensions.min.js"></script>
<!-- revert global jQuery and $ variables and store jQuery in a new variable -->
<script type="text/javascript">
var jQuery_1_1_3 = $.noConflict(true);
</script>
<!-- load jQuery 1.3.2 -->
<script type="text/javascript" src="http://code.jquery.com/jquery-1.3.2.js"></script>
<!-- revert global jQuery and $ variables and store jQuery in a new variable -->
<script type="text/javascript">
var jQuery_1_3_2 = $.noConflict(true);
</script>
The problem with this example is that after all this script runs, the $ and jQuery globals would be left in an undefined state (if nothing was loaded into them before this code.
This is significant because often times you are not just loading jQuery, but several plugins as well. The typical way that a plugin is installed is that it expects the global window.jQuery to exist and attaches itself to that global instance.
See my Part 2 blog for more information.
No comments:
Post a Comment