By Keith


2009-05-07 10:27:20 8 Comments

We have an application with legacy code that relies on prototype, but we've found it to be too 'heavy' for most of the places we want to use it and and have found jQuery to be a better fit for how we work. So we're migrating to jQuery for new functionality.

In the meantime we have several pages that need to load both libraries:

<script language="javascript" type="text/javascript"
        src="prototype-1.5.1.2.js"></script> 
<script language="javascript" type="text/javascript"  
        src="jquery-1.3.2.js"></script> 
<script language="javascript" type="text/javascript">
    $j = jQuery.noConflict();
</script> 

(note older version of prototype, we found issues on upgrading that we don't want to fix when we're phasing it out anyhow)

This works in IE6, IE7, IE8-as-7 and FX3, but load it in Chrome and all the jQuery stuff fails.

Loading up the developer javascript console displays the following errors:

Uncaught Error: NOT_SUPPORTED_ERR: DOM Exception 9 http://.../prototype-1.5.1.2.js (line 1272)
Uncaught TypeError: Object #<an Object> has no method 'ready' http://.../lib.js (line 161)
Uncaught TypeError: Object #<an Object> has no method 'slideUp' http://.../page.aspx (line 173)
... and so on - all the failures are missing jQuery methods

So this looks like a conflict in prototype that causes the creation of the jQuery object to fail.

The specific prototype issue appears to be Prototype.BrowserFeatures.XPath being true when it shouldn't be, as XPath document.evaluate isn't supported.

Ok, so now reload the page with the javascript console open - it all works! WTF? Close the console, reload and it fails again.

The failure only occurs when the page load occurs without the javascript console open - why would that make any difference? That looks very much like a bug in Chrome.

Anyone able to explain what's going wrong? Why should an error in prototype cause the jQuery init to fail? Why does loading the page with the console open make it work?

Anyone know a good workaround? (apart from upgrading to prototype-1.6.0.3.js, which fixes this issue but breaks a load of legacy code elsewhere)

2 comments

@hblanks 2009-12-16 15:11:16

I've found the root of this problem to be:

  1. Prototype loads, and because WebKit lacks document.getElementsByClass(), Prototype (insidously) creates it.

  2. jQuery initialization begins, and at the very top, it sets window.$ to jQuery.

  3. During JQuery's initialization, the Sizzle engine (added in 1.3.2?) initializes. As part of its introspection, it checks for, and then tests the functionality of document.getElementsByClass(). As a result, it calls Prototype's impelementation of getElementsByClass(), which depends on window.$ being set to Prototype's $, not jQuery's.

Ultimately, this will need to be fixed in jQuery (see tickets http://bugs.jquery.com/ticket/4365 and 5027). My quick patch was to remove the assignment to window.$ in the top of jQuery's initialization.

@vsync 2010-03-14 07:41:52

This is indeed the problem. as someone mentioned in the ticket, there's a section that can be wrapped in try/catch so go around this.

@Jake McGraw 2009-05-07 20:45:39

From Core/jQuery.noConflict:

NOTE: This function must be called after including the jQuery javascript file, but BEFORE including any other conflicting library, and also before actually that other conflicting library gets used, in case jQuery is included last. noConflict can be called at the end of the jQuery.js file to globally disable the $() jQuery alias. jQuery.noConflict returns a reference to jQuery, so it can be used to override the $() alias of the jQuery object.

Maybe try changing it to:

<script language="javascript" type="text/javascript"
  src="jquery-1.3.2.js"></script> 
<script language="javascript" type="text/javascript">
    $j = jQuery.noConflict();
</script>
<script language="javascript" type="text/javascript"
  src="prototype-1.5.1.2.js"></script>

@Keith 2009-05-08 08:18:44

That works, thanks. Any idea why the Chrome console fixes it too?

@Jake McGraw 2009-05-08 15:24:32

Using any kind of debugging tool (especially in-browser JavaScript tools) will cause code to execute in different way, "What we observe is not nature itself, but nature exposed to our method of questioning." (Heisenberg, Physics and Philosophy, 1963). Also, don't forget to accept my answer!

@blu 2009-11-18 20:24:07

+1 this helped me too. I'd like to point out there is conlflicting documentation to me careful of: docs.jquery.com/Using_jQuery_with_Other_Libraries

@vsync 2010-03-14 07:43:12

this is not always the case, and many times you have no control over the scripts in the page, lets say, if you make some sort 3rd party service which users add to their site/blog.

Related Questions

Sponsored Content

18 Answered Questions

[SOLVED] Disable/enable an input with jQuery?

30 Answered Questions

[SOLVED] jQuery scroll to element

41 Answered Questions

[SOLVED] Setting "checked" for a checkbox with jQuery?

56 Answered Questions

[SOLVED] How do I check if an element is hidden in jQuery?

32 Answered Questions

[SOLVED] Disable same origin policy in Chrome

65 Answered Questions

[SOLVED] How do I check whether a checkbox is checked in jQuery?

41 Answered Questions

[SOLVED] Is there an "exists" function for jQuery?

  • 2008-08-27 19:49:41
  • Jake McGraw
  • 733818 View
  • 2700 Score
  • 41 Answer
  • Tags:   javascript jquery

31 Answered Questions

35 Answered Questions

[SOLVED] Add table row in jQuery

Sponsored Content