Using Multiple jQuery Versions

Innately jQuery offers the possibility to use multiple jQuery versions at once or other libraries in combination with jQuery through the noConflict-mode. You should by all means avoid the overhead of two similar libraries in the same project. Unfortunately this is not always possible while using a CMS with sometimes a little outdated JavaScript libraries. In this article I will show you how to use the noConflict-mode and which characteristics you need to know about.

Embedding and Sandboxing Libraries

Lets assume that besides the jQuery version 1.3.2 (which comes with Drupal), we want to use the most recent version 1.8.2. To take a closer look at the pitfalls, we will sandbox each library with the noConflict-mode. Strictly speaking this has to be done only once, because you can always use the last library without noConflict.

<script type="text/javascript" src="jquery-1.3.2.min.js"></script>
<script type="text/javascript">
  var jQuery132 = $.noConflict(true);
</script>

<script type="text/javascript" src="jquery-1.8.2.min.js"></script>
<script type="text/javascript">
  var jQuery182 = $.noConflict(true);
</script>

In each case we embed the library itself and than release the registered $-sign immediately. Instead we assign each library to a custom variable, which we can later use to access the library directly.

If we want to use one of the libraries registered aboce, we will have to assign them to the $-sign again. We do this via sandboxing. Within the wrapper below the Dollar sign is automatically assigned to the library we add at the bottom. In this case the library with the version 1.8.2.

(function($) {
  // Your code goes here...
})(jQuery182);

Each Library only knows their own events

As the term Sandboxing suggests, each library is completely isolated from the other one. If we assign an event handler in one of the libraries, the other one doesn't know anything about it. In the following example I assume that some kind of Select is present on the website.

(function($) {
  $(document).ready(function() {
    $('select').change(function() {
      alert('jQuery 1.8.2');
    });
  });
})(jQuery182);

(function($) {
  $(document).ready(function() {
    // Nothing happens...
    $('select').trigger('change');
  });
})(jQuery132);

If you want to call events directly from another library, you can do this by using the global variable, we defined at the beginning of this article. By changing the example as follows, the event now actually gets triggered within the other library.

(function($) {
  $(document).ready(function() {
    // Alert: jQuery 1.8.2
    jQuery182('select').trigger('change');
  });
})(jQuery132);

Nesting is possible, but you shouldn't use it

It's actually possible to nest sandboxes into one another. The following code works flawlessly, but it's pretty difficult to read and understand. So I recommend to avoid constructs like that.

(function($) {
  $('select').change(function() {
    alert('jQuery 1.8.2');
  });

  (function($) {
    $('select').change(function() {
      alert('jQuery 1.3.2');
    });   

    // Alert: jQuery 1.3.2
    $('select').trigger('change');
  })(jQuery132);

  // Alert: jQuery 1.8.2
  $('select').trigger('change');
})(jQuery182);

I hope I could lift the secrets around the noConflict-mode at least a little bit and help one or another fellow developer.

Update 06/23/2013

Be careful with the parameter of noConflict. If you set this to true, all references to jQuery are removed from the document. Event the variable jQuery itself. Many plugins depend on the existance of this variable, because they use a wrapper, which might look something like this:

(function($) {
  $.fn.myPlugin(function() {
    // plugin code
  });
})(jQuery);

Because you removed jQuery from the global namespace, you need to add these libraries before your noConflict call. Like this:

<script src="jquery.0.8.15.js"></script>
<script src="myplugin.js"></script>
<script>// noConflict</script>

So you should embed scripts like this:

  1. First jQuery version
  2. Plugins for this version
  3. noConflict
  4. Next jQuery version
  5. Plugins for the next version