Fixing jQuery – Prototype Script Conflicts

Here’s a quick tip.

I was working on a little jQuery project this week. Everything was fine until I tried to implement it on a CMS page in Magento. When I did that, the Magento menu and cart functions stopped working.

A little searching around made it clear that the problem was a conflict between jQuery and prototype.

Magento uses prototype.js. I guess I knew that. I’d seen that getting loaded from Magento’s app/design/frontend/package/theme/layout/page.xml. And it’s well documented that the jQuery library and prototype library don’t play well together.

jQuery has a fix for this. It comes up if you Google it. It’s as “simple” as adding the following line:

jQuery.noConflict();

Then, whenever you’re going to do something with jQuery, use jQuery instead of the shorthand $ to call it. So, for example:

jQuery(document).ready(function() {
  jQuery('div').hide();
});

What’s not documented so well is exactly where, to put the jQuery.noConflict() line.

After a little tinkering, here’s what worked for me.

  1. Queue your scripts so that jQuery loads first.
  2. Add the jQuery.noConflict() line immediately following the jQuery library.
  3. Load any other jQuery-related libraries (for example, jQuery-migrate or jQuery-UI).
  4. Load prototype last.

You might even add the noConflict line directly to the end of your jquery-x.y.z-min.js file if you’re loading it from a self-hosted location (à-la Magento).

Once you’ve loaded all that you can call jQuery stuff as shown in the example above, and prototype stuff using the $ shortcut.

And, if you want to get really fancy, you can re-shorten the jQuery calls by changing the noConflict line to:

var j$ = jQuery.noConflict();

Then call jQuery stuff using  j$(document).ready(function() { ...

Happy scripting!