35

Several of my pages use both JQuery and Protoype. Since I upgraded to version 1.3 of JQuery this appears to be causing problems, because both libraries define a function named '$'.

JQuery provides a function noConflict() which relinquishes control of $ to other libraries that may be using it. So it seems like I need to go through all my pages that look like this:

<head>      
    <script type="text/javascript" src="/obp/js/prototype.js"></script>
    <script type="text/javascript" src="/obp/js/jquery.js"></script>
</head>

and change them to look like this:

<head>      
    <script type="text/javascript" src="/obp/js/prototype.js"></script>
    <script type="text/javascript" src="/obp/js/jquery.js"></script>
    <script type="text/javascript">
        jQuery.noConflict();
        var $j = jQuery;
    </script>
</head>

I should then be able to use '$' for Prototype and '$j' (or 'jQuery') for JQuery. I'm not entirely happy about duplicating these 2 lines of code in every relevant page, and expect that at some point somebody is likely to forget to add them to a new page. I'd prefer to be able to do the following

  • Create a file jquery-noconflict.js which "includes" jquery.js and the 2 lines of code shown above
  • Import jquery-noconflict.js (instead of jquery.js) in all my JSP/HTML pages

However, I'm not sure if it's possible to include one JS file in another, in the manner I've described? Of course an alternate solution is simply to add the 2 lines of code above to jquery.js directly, but if I do that I'll need to remember to do it every time I upgrade JQuery.

5
  • Does answer I provided works for you? Commented Jan 16, 2012 at 10:29
  • 1
    Dunno, it's been 3 years since I asked this question... Commented Jan 16, 2012 at 10:49
  • Ok.. :) I missed that.. :) But I think the principle is correct as I tried it out... Commented Jan 16, 2012 at 10:51
  • 1
    Obviously this is old, but I had a situation where I had to change 5 lines of code in 63 html files (I didn't build the website). Some regex replace, and replace in files did the trick in a few seconds. Notepad++ will do it to a limited degree, and submlime text editor did it like a champ. Commented Apr 29, 2012 at 3:04
  • @DavidHobs: +1 for Sublime! It's the best thing since sliced bread! Commented Jun 7, 2013 at 6:52

12 Answers 12

19

Currently you can do something like this:

<head>          
    <script type="text/javascript" src="/obp/js/prototype.js"></script>
    <script type="text/javascript" src="/obp/js/jquery.js"></script>
    <script type="text/javascript">
        var $j = jQuery.noConflict();
    </script>
</head>

Then, use jQuery as $j() and Prototype's $().

Sign up to request clarification or add additional context in comments.

1 Comment

This was very helpful to me on a similar issue. Thank you jmonteiro :)
5

It would seem that the most simple answer would be to bite the bullet, and include your noConflict lines. Of course if your pages aren't using a shared header, that solution might not be the best.

Comments

5

This solution worked fine:

jQuery.noConflict();
var $j = jQuery;

Now use $j in place of $ for your jQuery code, like:

$j(document).ready(function() {
    $j('#div_id').innerfade({
         // some stuff
    });
});

Comments

3

I went through this for a while. It is very annoying and in the end I decided to weed out all of my old Prototype stuff and replace it with jQuery. I do like the way Prototype handles some Ajax tasks but it wasn't worth the trade off of maintaining all of the no conflict stuff.

1 Comment

+1 It's always a good idea to reduce the used frameworks. Not only in terms of conflicts but also in terms of a light-weight application event if it requires some refactoring to eliminate prototype.
2

Just as a note to others that stumble upon this. The solutions are described here (mentioning prototype specifically): http://docs.jquery.com/Using_jQuery_with_Other_Libraries

Comments

2

Could you not just include the jQuery = noConflict() code in the jquery.js source file? Why would it need to be defined that way?

Comments

1

Your jquery-noconflict.js should look like this (be sure that all is in one line):

document.write("<script type=\"text/javascript\" src=\"/obp/js/jquery.js\"></script><script type=\"text/javascript\">jQuery.noConflict();var $j = jQuery;</script>");

... and than your include (as you already pointed out) should look like this:

<head>      
    <script type="text/javascript" src="/obp/js/prototype.js"></script>    
    <script type="text/javascript" src="/obp/js/jquery-noconflict.js"></script>
</head>

This solution solves all your requirements I think.

Comments

1
<script>
    document.write(unescape('%3Cscript type="text/javascript" src="/obp/js/jquery.js"%3E%3C/script%3E'));
</script>
<script>
    jQuery.noConflict();
    var $j = jQuery;
</script>

or

var scripty = document.createElement('script');
scripty.href="/obp/js/jquery.js";
document.getElementsByTagName('head')[0].appendChild(scripty);
jQuery.noConflict();
var $j = jQuery;

EDIT:

I tried out this suggestion but the last 2 lines produce the error

jQuery is not defined

2 Comments

You need to specify a callback when the script loads to run the noconflict code... just do a .appendChild(scripty) scripty.onload = setNoconflict; function setNoconflict(){ jQuery.noConflict(); $j = jQuery; }
@jacobangel your first example works, but I removed a typo (see diff) and made a correction: it's important to close the script tag after document.write(..) and open up a new one where jQuery.noConflict() is in. Otherwise jQuery is not defined because document.write is appending the jQuery-script after the current script block.
1

You could call jquery first and then set

var $j = jQuery;

prototype will take control of $ in this case.

Or, you could just refer to jQuery by using the full jQuery function name (jQuery).

Comments

0

Use Prototype below jQuery like this:

<script type="text/javascript" src="news/jquery-1.2.3.pack.js"></script>
<script type="text/javascript" src="news/jquery.easynews.js"></script>


<script type="text/javascript" src="lb/js/prototype.js"></script>
<script type="text/javascript" src="lb/js/scriptaculous.js?load=effects"></script>
<script type="text/javascript" src="lb/js/lightbox.js"></script>
<link href="lb/css/lightbox.css" rel="stylesheet" type="text/css" />

in this case the jQuery function will create a problem, so you can use this to solve the problem:

<script type="text/javascript">
     jQuery.noConflict();
     var JQ = jQuery;//rename $ function
</script>

Comments

0

If I were you, I'd drop my no conflict code into a JavaScript include file like you opined about above, and then figure out some process where I'd be setting these things I need to include in all my pages in one central place. If you are working with straight HTML files and you don't have any kind of templating/scripting capability server-side for what gets included in a document, there's always the possibility of doing a Server-Side Include.

Either way, the pain you'll experience updating each of your pages this time will come back again when you need to update your analytics code or the site footer.

Comments

0

You need to load it in your public/javascript/application.js

jQuery.noConflict();

var $j = jQuery;

This is also a good article that may be helpful.

JQuery & Prototype working together

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.