21

I just cannot work this out. My god it's making my brain hurt, so I turn to you, the good people of the internet.

I've been staring at the documentation for the jQuery $.noConflict() function with no luck.

My issue is that the site I'm working on already includes jQuery 1.1.3.1 but I want to do some awesome and snazzy UI work in a few places, so I want to use 1.4.2 for obvious reasons.

I've been trying to run these side by side but I can't seem to get any code to execute. I also need to implement a few plugins using 1.4.2 so I'm not sure if putting jQuery over to something like $j would work, as obviously the plugins would pick up $ and jQuery as 1.1.3.1 rather than 1.4.2.

Is there a way that I can wrap my code in a noConflict() block and also include the plugins that I need to create a self contained block of 1.4.2 code?

Any help would be fantastic as my poor mind weeps amid the vast wasteland that is the API docs!

hippietrail
  • 15,848
  • 18
  • 99
  • 158
David Yell
  • 11,756
  • 13
  • 61
  • 100
  • 2
    Whoa... Maybe try convincing peeps who run that site to update whatever script they are using that needs that jquery 1.1.3.1 :) Much simpler solution, dont you agree? :) – Gavrisimo Jul 06 '10 at 16:42
  • 1
    @Gavrisimo solution is only simple if da peeps is simple to convince (-: In any case it's a practical and interesting problem. – hippietrail Sep 01 '12 at 10:59
  • It's a shame that my english isn't good enough for SO. – David Yell Sep 04 '12 at 12:34

8 Answers8

27

If you have two or three jQuery in the same page, just put a different variable for each different jQuery.

Example:

<script type="text/javascript">
    var $s = jQuery.noConflict();
    $s(document).ready(function() {
        $s('#news-container').vTicker({
            speed: 500,
            pause: 3000,
            animation: 'fade',
            mousePause: true,
            showItems: 2
        });
    });
</script>
<script type="text/javascript">
    var $j = jQuery.noConflict();
    $j(document).ready(function() {
        $j('.sf-menu ul').superfish({
            delay: 1000,
            animation: {
                opacity: 'show',
                height: 'show'
            },
            speed: 'medium',
            autoArrows: false,
            dropShadows: 'medium'
        });
    });
</script>
jackJoe
  • 11,078
  • 8
  • 49
  • 64
jamsheed
  • 271
  • 3
  • 3
  • 2
    In my case, just $s fixed my problem, I didn't need $j too. I have a WYSIWYG editor on just one page that needs "jQuery v1.6.1" and this solution fixed my conflict. – PJ Brunet Feb 22 '14 at 08:28
  • 2
    Here's what I don't understand about this answer: How does the script determine which version $s points to and which version $j points to? – Mark Jun 04 '15 at 00:19
  • @Mark the last version loaded is the first version you rebind to another variable, take also a look on the examples at the bottom of the API description here http://api.jquery.com/jQuery.noConflict/ – thex Dec 11 '18 at 23:06
6

You should simply upgrade the entire site to 1.4.2.
jQuery does not in general have many breaking changes, so that shouldn't be so hard.

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
  • 2
    I would dearly love to do this, but I would mean massive changes across the whole site, and replacing lots of ajax and plugins also. The whole application folder is 1.22gb so you can imagine the codebase I'm dealing with! – David Yell Jul 06 '10 at 16:53
  • 4
    I ended up upgrading the library and rebuilding a bit of the js! – David Yell Jul 14 '10 at 15:20
  • 2
    @DavidYell definitely the best solution! – RYFN Jul 15 '10 at 11:46
  • While I agree in theory, note that It's not always possible to upgrade the whole site to a single version - especially if you're using a framework, including a library that itself includes a conflicting version of jQuery, or doing any kind of "scraping" of content from another page. Indeed, if you're doing more than one of these things (and in industry you sometimes have no choice), there's often no other option besides skillful use of noconflict mode. – Andrew Faulkner Sep 08 '15 at 05:13
5

I had a similar issue recently where I was using jQuery v1.3.2 on a page but a 3rd party questionnaire popup was using an older version on the same page. I eventually managed to solve the problem. I referenced jQuery 1.3.2 as follows:

 <script type="text/javascript" src"/Scripts/jquery-1.3.2.min.js"></script>
    <script type="text/javascript"> 
        jq132 = jQuery.noConflict(true); 
 </script> 

I then modified all my jQuery code to use jq132 instead of $. I then did a find and replace on all of the plugins I was using to replace "$(" with "jq132(" and "$." with "jq132.". There may be a more elegant approach but this worked for me. I'm far from a jQuery expert so there may be other $ syntax that you need to handle (i.e. not just "." and "(").) .

j.strugnell
  • 407
  • 1
  • 3
  • 15
3

You should post an example that isn't working. I bet we'd clear it up immediately.

I don't believe noConflict is a 'block' exactly. You use noConflict to tell jQuery that you want it to remove anything it declares from the global JavaScript namespace (because you want to load jQuery again and reuse those names).

On a page with more than 1 instance of jQuery loaded, both instances should use noConflict. I don't know if it's possible to load a second instance of jQuery if there's already an instance loaded and that instance didn't call noConflict.

@SLaks and @galambalazs: Sometimes you're writing a small amount of content that will be displayed within a larger page, such as a portal. The portal already uses a(n outdated) version of jQuery, but you need a newer version. Also you don't control the larger portal page, just the content you're writing that will be displayed within it.

This scenario accurately describes real work I do commonly.

Drew Wills
  • 8,408
  • 4
  • 29
  • 40
  • This will cause all sorts of issues, since `jQuery` is the object name, plugins are extending...what? The last one that was loaded before it executes, and any loading jQuery clears all plugins of the one before...this is only the tip of the iceberg in terms of issues, it's just not designed to do this. – Nick Craver Jul 06 '10 at 16:53
  • 1
    Check out this excellent writeup from a colleague of mine: https://isa.its.yale.edu/confluence/display/YIP/jQuery+in+uPortal+3.1 jQuery *is* designed to do this. You have to load the plugins you want to use after you load jQuery itself, but *before* you call noConflict. Then you do your page setup work in an anonymous function wherein the jQuery instance can be assigned to the standard $ variable for simplicity & clarity. – Drew Wills Jul 06 '10 at 17:03
2

I would agree with other posts that suggest trying to upgrade to 1.4.2 across the board... That said, you clearly have a good reason for attempting what you are trying to do. To my knowledge there is no easy way to deal with your situation (as I too have tried something similar).

"noConflict" simply releases the global "$" variable so that other libraries/scripts may safely use it. Given that you are trying to use two versions of jQuery "noConflict" isn't really helpful here...calling it for both versions of jQuery doesn't change the fact that both versions still need to reference the global "jQuery" object (of which there can only be one...).

The issue (as you clearly already know) is that loading the 2nd jQuery version will "clobber" the original jQuery object (and all the "customizations" made to it by plug-ins).

The only reliable (albeit incredibly inefficient) solution I could come up with is:

  • Load the existing (old) jQuery version and plugins (assuming you can't avoid this)
  • Load the new jQuery version
  • RE-load and existing plugins and any new plugin you want to use
  • Test extensively
droo
  • 1,059
  • 6
  • 5
  • This had not occured to me, but it's a great suggestion. Unless I can persuade my boss to let me upgrade everything! ;) – David Yell Jul 07 '10 at 07:56
0

WAY late .... but might help someone - threw this together.

/**
*********************************************************************************************************
*           jQuery version check
*           $.noConflict() is not enough to ensure jQuery as well as $ 
*           has correct version (can cause troubles with jQuery plugins that use fn(){}(jQuery);
*
*           useage: restoreJquery('1.10.2',true) //for unminimized dev version
*                   restoreJquery('1.10.2')          //for minimized version
*                   restoreJquery('1.10.2',true,myFunction)          //for minimized version, that executes a function once jQuery is in the page
*
*
**/

function restoreJquery(wantedVersion,devVersion,callback) {
    if(!wantedVersion){
        wantedVersion= '1.10.2';
    }

    //is current jQuery version ===wanted version? (double check to avoid undefined errors)
    if($ && $.fn.jquery!==wantedVersion){                

        //if not invoke noConflict with true (true=gives up the jQuery name space aswell as $)
        var $jQuery = jQuery.noConflict(true); 
        //Line Assign the new object to new instantiated versions of jQuery
        var $=jQuery=$jQuery;                          
      }

    //if jQuery is still not the correct version inject it into page via plain vanilla js

    //if $ does not exist or the version is wrong inject it into the page
    if(!$ || $.fn.jquery!==wantedVersion){ 

        var head=document.getElementsByTagName('head')[0], //get Head
            jqPath=wantedVersion+'jquery.', // ex '1.10.2/jquery.
                    script=document.createElement('script'); //create empty scripttag

            if(devVersion){  //minimized or not?
                jqPath+='min.js';
            }else{
                jqPath+='js';
            }

        script.src='//http://ajax.googleapis.com/ajax/libs/jquery/'+jqPath; //create src path
        script.type='text/javascript'; //add type
        script.async=true; //set async to true
        //real browsers
        script.onload=callback;  //call callback on load

        //Internet explorer doesnt support onload on script (typical ie)
        script.onreadystatechange = function() {
            if (this.readyState == 'complete') {
                callback();
            }
        }


    head.appendChild(script);

    }else{
        //otherwise call the callback since noConflict solved our jQuery versioning issues
        callback();
    }

};
klaus
  • 1
0

A solid advice: don't stress your and your visitors bandwidth with two jQuery versions. Change your whole codebase to the latest version. It's got less bugs, more support and improved behavior.

gblazex
  • 49,155
  • 12
  • 98
  • 91
  • Bandwidth isn't a major concern, since it'll be cached and all, I'd be more worried about 2 versions, ya know, breaking everything. – Nick Craver Jul 06 '10 at 16:44
  • 1
    Oh we have 1.2.1 on there also! ;) ..and my codebase is 1.22gb! – David Yell Jul 06 '10 at 16:51
  • Bandwidth isn't a major concern?? IT IS! You can't count on caching. http://stackoverflow.com/questions/3111468/speed-performance-reduce-http-requests-or-not/3137112#3137112 – gblazex Jul 06 '10 at 16:54
  • 1
    @galambalazs - Caching is a lot more dependable than your answer suggests, don't dismiss it. But all of that's beside the point. **This will break his page**, the amount of bandwidth used is secondary to none of it working. – Nick Craver Jul 06 '10 at 16:58
  • @Nick secondary for you, not so secondary for your users. It's all about users. It's always been... Don't let them suffer for your design decisions. – gblazex Jul 06 '10 at 17:04
  • 2
    @galambalazs - I think you completely missed the point here. A broken page is the *primary* concern. You would rather deliver a low-bandwidth completely broken page than a larger yet working one? I don't know of a single developer who would make that decision... **Of course bandwidth is a concern**, but it's *secondary* to making it work in the first place. – Nick Craver Jul 06 '10 at 17:09
  • @Nick of course he should make it work, but since the whole development is stuck, why not **leave legacy code behind** and make it work with **less bandwith** and a **more stable library**. – gblazex Jul 06 '10 at 17:13
  • @Nick you see, the point here is he got a chance to start over, if he won't his users will suffer. And they will suffer for a long time, because the application will be bound to the legacy library for another couple of years. – gblazex Jul 06 '10 at 17:14
  • 1
    @galambalazs - I don't disagree, I've answered this [plenty of times before](http://stackoverflow.com/questions/3061618/using-different-versions-of-jquery-on-the-same-page/3061647#3061647), nowhere did I advocate leaving 2 libraries, read through my comments or any of my ~2500 answers on this site...I'll never advocate that :) I'm just saying bandwidth is not the **current** problem. Even in your comments you agree the main issue is the **old library**, not the *bandwidth*, it's "secondary". :) Also look at Drew's answer, removing the old library isn't always *your* decision to make. – Nick Craver Jul 06 '10 at 17:27
0

jQuery no-conflict is an option given by jQuery team to overcome the conflicts between the different JS frameworks or libraries. We are replacing the $ to a new variable and assigning to jQuery when we use the noconflict method.

    <button>Test jQuery noConflict</button>
    <script>
        var newjq = $.noConflict();
        newjq(document).ready(function(){
           newjq("button").click(function(){
               newjq("p").text("Wahh..! Its working!");
            });
        });
    </script>

We can use the $ sign like below also, it not create any conflict also

$.noConflict();
jQuery(document).ready(function($) {
   // Code that uses jQuery's $ can follow here.
});
Srikrushna
  • 4,366
  • 2
  • 39
  • 46