2

I'm including jQuery and a custom .js file into the master page of my SharePoint 2010 site. In the $(document).ready() function, I'm setting a live event handler on an element in the header of the page.

When I view the page, the jQuery event fires and processes the event correctly. If I edit the page and then save it, my event fires.

But if I edit the page and add a web part, for example the stock Images list web part for testing, the jQuery event no longer fires. jQuery and my custom file are still be included according to the dev tools source/script views.

Originally, I had the code being called repeatedly, every half-second, using setInterval(). That behaved the same way - it worked on every page until certain web parts were added. After that, it no longer worked until I edited the page again and removed the web part.

I say certain web parts because I haven't tried them all, but some, like the Calendar control, don't seem to cause the problem. The Images list always does.

Any ideas?

3 Answers 3

6

This is a common problem when using multiple JavaScript libraries as many of them define $()

SharePoint is using ASP.NET Ajax so if you include JQuery you should do that in noConflict mode.

You turn that on using

jQuery.noConflict();

Now $ will never mean jQuery unless you use constructs like:

jQuery(document).ready(function($){
    /* code using $ */ 
});

or

(function($) {
    /* code using $ */ 
})(jQuery);
3

Best practice: Whenever you use JQuery in your solutions, you should use something like the Revealing Module Pattern or similar to hide away the implementation of your variable and use of JQuery (and $) behind a namespace. This also allows you to force use of specific JQuery versions for different parts.

Example:

// Load JQuery with noConflict()
var jq171 = = jQuery.noConflict();


> File MyModule.js

// MyModule namespace root
window.MyModule = window.MyModule || {};

// ====================
// Some submodule
// ====================
(function (Submodule, $, undefined) {
    // Private properties
    var howMany = 5;

    // Public properties
    Submodule.someproperty = 8;
    ...

    // Public methods

    Submodule.initialize = function () {
       $(document).ready( function () {
            // hook up to DOM here
       });
    }

    ... 

    // Private methods
    function toggleSomethingSuccess(data) {
        if (data != '') {
            // redirect to new or existing page
            window.location = data;
        }
    }

    ...

} (MyModule.Submodule = MyModule.Submodule || {}, jq171));

Then you just use

MyModule.Submodule.initialize();

This will protect your code from others, and others from you. Win-win.

1

Here is what appears to have been happening. If you know of a better workaround or alternate explanation, let me know.

I was including the jQuery file and then my custom jQuery code in another file. All of my init was in my $(document).ready() and it, among other things, started a polling process using setInterval().

With no extra web parts on the page, it all worked great. When I added some types of web parts, the $(document).ready() might or might not complete and the routine being called by setInterval() might run once or twice. Made it hell to debug.

Apparently, one or more web parts were dynamically loading JavaScript that redefined $ to not be a synonym for jQuery, so the first few lines of my code would work, then the web part code would be loaded, then all of my $(...) functions would bomb out.

Changing my code from $("selector").whatever() to jQuery("selector").whatever() fixed the problem as far as I can tell, but that was some fairly annoying an unpredictable behavior (or at least a Microsoft caveat that I overlooked somewhere).

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.