Blog

Nov 20

Written by: Mark Allan
Fri, 20 Nov 2009 16:45:14 GMT 

As you can see, most of the menu templates for the DDRMenu make use of jQuery. We all love jQuery, it makes our sites fast and pretty! Unfortunately, as several people have noticed, even with the jQuery support added in DNN v5 it is still difficult to use jQuery in a DNN module or skin object without running the risk of conflicting with another module on the site that also uses it. The trouble is, when you’re building a module for general distribution any of the following might or might not be the case:

  • The skin or DNN portal doesn’t load jQuery at all.
  • The skin or DNN portal loads a version of jQuery earlier than the one you need.
  • A module further up the page loads a version of jQuery earlier than the one you need.
  • A module further down the page is going to load a version of jQuery earlier than the one you need and splat your instance.

There’s been a bit of community discussion about how best to get around this, so I thought I’d share my approach. Basically, I came to the conclusion that server side code wouldn’t be able to handle a badly behaved module that loaded jQuery v1.1 into the middle of the page when v1.3 was needed, so I went for the following client-side method:

  1. If a suitable version of jQuery is already loaded, store a reference to it.
  2. If not, load the preferred version of jQuery and store a reference to it, but use noConflict(extreme) to avoid affecting any earlier version of jQuery that has been loaded.
  3. Use the failsafe version of the ready function to allow safe use of the $ alias.

The actual code looks like this (assuming we need version 1.3):

<script type="text/javascript"> 
    // If we don’t already have a jQuery reference stored from another module 
    if (!window.myjQuery) { 
        // If supported version of jQuery already loaded 
        if (window.jQuery && (jQuery.fn.jquery >= "1.3")) 
            // save a reference to it 
            myjQuery = jQuery; 
        else 
            // Load our required version of jQuery 
            document.write('<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js" type="text/javascript"></' + 'script>'); 
    } 
</script> 
<script type="text/javascript"> 
    // If we didn’t manage to get a reference to an already loaded jQuery 
    if (!window.myjQuery) 
        // Store a reference to the one we loaded in extreme no-conflict 
        // mode in case a previous version was already loaded 
        myjQuery = jQuery.noConflict(true); 
</script> 
<script type="text/javascript"> 
    // Call the ready function specifying the $ alias 
    myjQuery(function($) { 
        // Your module's jQuery code goes here 
        $("p").text("DNN plus jQuery rocks!"); 
    } 
</script>

It’s a lot smaller if you get rid of the comments and whitespace, of course! Also, being entirely run on the client, it also should work in any other CMS, regardless of the server platform.

Anyway, I’d be interested to hear what others think of this approach. Are there any problems you can see with it?

Tags:

4 comment(s) so far...

Re: Avoiding jQuery conflicts in DotNetNuke modules

Great information Mark!

May I ask why three scripts instead of one?

By Vasilis on   Sat, 21 Nov 2009 08:35:02 GMT

Re: Avoiding jQuery conflicts in DotNetNuke modules

@Vasilis,

Good question! Basically, when you dynamically include a script using document.write(), it's not available to you in the current script block, which is why the first and second blocks are separated. The third block is separate simply because in general you're going to be using an external JS file rather than having it inline.

By Mark Allan on   Sat, 21 Nov 2009 08:47:01 GMT

Re: Avoiding jQuery conflicts in DotNetNuke modules

Hi Mark,

I'm looking for ways to do the same thing and came across your article. How have you handled other modules such as jQuery.UI which references the jQuery object? Are you changing all references to jQuery in the jQuery.UI library to myjQuery?

By Richard on   Thu, 28 Jan 2010 20:59:54 GMT

Re: Avoiding jQuery conflicts in DotNetNuke modules

@Richard,

Yes, I would use the same method to check whether the required bits of jQuery UI are already loaded, and if not then load a modified version with the initial reference to jQuery changed to myJquery. You only need to change it in the outer method call - everything else is locally scoped and doesn't need to be changed.

By Mark Allan on   Thu, 28 Jan 2010 21:09:25 GMT

Your name:
Your email:
(Optional) Email used only to show Gravatar.
Your website:
Title:
Comment:
Add Comment   Cancel