465

A project I'm working on requires the use of jQuery on customers' Web pages. Customers will insert a chunk of code that we'll supply which includes a few <script> elements that build a widget in a <script>-created <iframe>. If they aren't already using the latest version of jQuery, this will also include (most likely) a <script> for Google's hosted version of jQuery.

The problem is that some customers may already have an older version of jQuery installed. While this may work if it's at least a fairly recent version, our code does rely on some recently introduced functionality in the jQuery library, so there are bound to be instances when a customer's jQuery version is just too old. We can't require that they upgrade to the latest version of jQuery.

Is there any way to load a newer version of jQuery to use only within the context of our code, that will not interfere with, or affect, any code on the customer's page? Ideally, maybe we could check for the presence of jQuery, detect the version, and if it's too old, then somehow load the most recent version just to use for our code.

I had the idea of loading jQuery in an <iframe> in the customer's domain that also includes our <script>, which seems like it might be feasible, but I'm hoping there's a more elegant way to do it (not to mention without the performance and complexity penalties of extra <iframe>s).

tshepang
  • 12,111
  • 21
  • 91
  • 136
Bungle
  • 19,392
  • 24
  • 79
  • 106
  • 1
    I ran into the same problem. Since I only used jQuery a handful of times in my embedded script, I decided to forego jQuery altogether and simply do what I needed directly in JavaScript. This site: http://youmightnotneedjquery.com/ was extremely useful. – Ferruccio Feb 11 '15 at 12:02

8 Answers8

621

Yes, it's doable due to jQuery's noconflict mode. http://blog.nemikor.com/2009/10/03/using-multiple-versions-of-jquery/

<!-- load jQuery 1.1.3 -->
<script type="text/javascript" src="http://example.com/jquery-1.1.3.js"></script>
<script type="text/javascript">
var jQuery_1_1_3 = $.noConflict(true);
</script>

<!-- load jQuery 1.3.2 -->
<script type="text/javascript" src="http://example.com/jquery-1.3.2.js"></script>
<script type="text/javascript">
var jQuery_1_3_2 = $.noConflict(true);
</script>

Then, instead of $('#selector').function();, you'd do jQuery_1_3_2('#selector').function(); or jQuery_1_1_3('#selector').function();.

VLAZ
  • 26,331
  • 9
  • 49
  • 67
ceejayoz
  • 176,543
  • 40
  • 303
  • 368
  • 14
    Thanks very much, ceejayoz! That looks like a viable solution - the only potential problem is that I don't have any control over the first part of your code solution (assigning the older version of jQuery to a different alias). How the customer is using jQuery will vary and is outside of my control. Can I safely just use the latter half, or do both libraries need to call noConflict()? – Bungle Oct 14 '09 at 15:05
  • 7
    Yes, you should be able to just use the second half. – ceejayoz Oct 14 '09 at 16:24
  • 11
    Is this really transparent to the original page? If they use $ or jQuery *after* this piece of code, would this refer to their own jQuery version or the newer one (which possibly has fewer plugins installed)? – Wim Jan 17 '11 at 23:18
  • 1
    One important caveat to this answer is that you need to make sure you older version plugins are loaded before the new jQuery and thats still assuming the plugins are written correctly (passing jQuery object as an argument for $) – Adam Gent Jun 03 '11 at 20:19
  • @Wim $ and jQuery is going to refer to the first jquery loaded on the page (no matter how many $.noConflict(true) are done, or weather after the first loaded jquery a $.noConflict(true) is done). @ Adam Gent, the only thing you should do is advise the page owner to place your (noConflict) code after his(hers) jquery script tag. The rest of his(hers) scripts don't matter (weather they'll be before or after your (noConflict) code. – despot Nov 07 '12 at 17:33
  • 2
    @ceejayoz, what happens if you have a self-invoking function that uses a lot of $ within it. We would have to change every single $ to jquery_1_3_2, within that noconflict section??? – klewis Apr 30 '13 at 17:38
  • 42
    @blachawk No, just alias it. `(function($) { /*your code here*/ }(jquery_x_x_x));` – Fabrício Matté May 09 '13 at 22:58
  • Until now I've been reluctant to use this technique because the jQuery team say in their [api docs](http://api.jquery.com/jQuery.noConflict/) that having two versions of jQuery loaded is "not recommended" but then they go on to show you how it is done, so maybe it's ok after all. – Glenn Lawrence Aug 15 '13 at 00:02
  • Is it possible to apply alias for a specific function or scope? For example I want my 3d party plugin to use a version of jquery I explicitly specified (and load it right before that usage) while all the rest of my code to use whatever it was using before. – Mando Nov 02 '16 at 12:14
  • Do I need to prepend the jquery version to the selectors for both versions, or can I just prepend `jQuery_1_1_3('#selector').function();` on selectors that apply to my older 1.1.3 version? (leaving selectors that apply to my newer jQuery version looking the same: `('#selector').function();` – Kyle Vassella Dec 08 '17 at 18:27
  • @KyleVassella You still need to give the default version an alias. You can just load the default jQuery and do this: var jQuery = $.noConfilct(true). Then you can still use jQuery for most of the code and only jQuery_version for the specific old version. unlike Adam Gent said, I load the newer version jQuery first without any issue. – Weihui Guo Aug 23 '18 at 13:09
98

After looking at this and trying it out I found it actually didn't allow more than one instance of jquery to run at a time. After searching around I found that this did just the trick and was a whole lot less code.

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js" type="text/javascript"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js" type="text/javascript"></script>
<script>var $j = jQuery.noConflict(true);</script>
<script>
  $(document).ready(function(){
   console.log($().jquery); // This prints v1.4.2
   console.log($j().jquery); // This prints v1.9.1
  });
</script>

So then adding the "j" after the "$" was all I needed to do.

$j(function() {
  $j('.button-pro').on('click', function() {
    var el = $('#cnt' + this.id.replace('btn', ''));
    $j('#contentnew > div').not(el).animate({
      height: "toggle",
      opacity: "toggle"
    }, 100).hide();
    el.toggle();
  });
});
VLAZ
  • 26,331
  • 9
  • 49
  • 67
Weird Mike
  • 1,207
  • 9
  • 14
  • 8
    To avoid renaming jquery variable in so many places you could just enclose your old code inside the following: `(function($){ })($j)` – Marinos An Apr 23 '18 at 12:43
38

Taken from http://forum.jquery.com/topic/multiple-versions-of-jquery-on-the-same-page:

  • Original page loads his "jquery.versionX.js" -- $ and jQuery belong to versionX.
  • You call your "jquery.versionY.js" -- now $ and jQuery belong to versionY, plus _$ and _jQuery belong to versionX.
  • my_jQuery = jQuery.noConflict(true); -- now $ and jQuery belong to versionX, _$ and _jQuery are probably null, and my_jQuery is versionY.
Matt
  • 74,352
  • 26
  • 153
  • 180
Juan Vidal
  • 541
  • 5
  • 5
  • 11
    I didn't understand until i went to the link. "When you load your jQuery.x.x.js, it will overwrite the existing $ and jQuery vars... BUT it keeps a backup copy of them (in _$ and _jQuery). Calling noConflict(true) you restore the situation as it was before your js inclusion" – Colin Feb 21 '12 at 12:14
  • In future, please be more explicit about referencing external sources. For more information, see http://stackoverflow.com/help/referencing – Matt Sep 01 '15 at 12:23
25

It is possible to load the second version of the jQuery use it and then restore to the original or keep the second version if there was no jQuery loaded before. Here is an example:

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
<script type="text/javascript">
    var jQueryTemp = jQuery.noConflict(true);
    var jQueryOriginal = jQuery || jQueryTemp;
    if (window.jQuery){
        console.log('Original jQuery: ', jQuery.fn.jquery);
        console.log('Second jQuery: ', jQueryTemp.fn.jquery);
    }
    window.jQuery = window.$ = jQueryTemp;
</script>
<script type="text/javascript">
    console.log('Script using second: ', jQuery.fn.jquery);
</script>
<script type="text/javascript">
    // Restore original jQuery:
    window.jQuery = window.$ = jQueryOriginal;
    console.log('Script using original or the only version: ', jQuery.fn.jquery);
</script>
VLAZ
  • 26,331
  • 9
  • 49
  • 67
Tomas Kirda
  • 8,347
  • 3
  • 31
  • 23
25

You can have as many different jQuery versions on your page as you want.

Use jQuery.noConflict():

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js" type="text/javascript"></script>
<script>
    var $i = jQuery.noConflict();
    alert($i.fn.jquery);
</script> 

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
    var $j = jQuery.noConflict();
    alert($j.fn.jquery);
</script> 

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script>
    var $k = jQuery.noConflict();
    alert($k.fn.jquery);
</script> 

DEMO | Source

VLAZ
  • 26,331
  • 9
  • 49
  • 67
martynas
  • 12,120
  • 3
  • 55
  • 60
5

I would like to say that you must always use jQuery latest or recent stable versions. However if you need to do some work with others versions then you can add that version and renamed the $ to some other name. For instance

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js" type="text/javascript"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js" type="text/javascript"></script>
<script>var $oldjQuery = $.noConflict(true);</script>

Look here if you write something using $ then you will get the latest version. But if you need to do anything with old then just use$oldjQuery instead of $.

Here is an example:

$(function(){console.log($.fn.jquery)});
$oldjQuery (function(){console.log($oldjQuery.fn.jquery)})

Demo

VLAZ
  • 26,331
  • 9
  • 49
  • 67
Ananda G
  • 2,389
  • 23
  • 39
1
<script type="text/javascript" 
src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script>var $j = $.noConflict(true);</script>

It was not working for me then I changed it to

<script>var jQuery = $.noConflict(true);</script>

and it worked for me.

VLAZ
  • 26,331
  • 9
  • 49
  • 67
Safeer Ahmed
  • 587
  • 6
  • 14
1

To further improve Juan Vidal's answer, it is worth noting that if you use multiple jquery plugins with one version (eg 3.3.1) and multiple jquery plugins with another version(eg 1.10.2), for older version to work (and it's plugins) you must dig into plugin's minified/unminified .js file(s) and alter the line that will be something like this:

Example 1: module.exports=a:a(jQuery) to module.exports=a:a(my_jQuery)
Example 2: b(a,require("jquery")):b(a,a.jQuery)} to this: or b(a,require("jquery")):b(a,a.my_jQuery)}
TomoMiha
  • 1,218
  • 1
  • 14
  • 12