none
SharePoint custom JavaScript and jQuery blocked by MDS Minimal Download Strategy

    Question

  • Hi folks 

    Here's my setup. Onprem SharePoint 2016. I have a master page which is basically a copy of seattle.master and I want to add jQuery and a custom Javascript to manipulate the DOM. The minimal download strategy blocks my code. I read numerous posts but I just cannot figure it out of the life of me. I know I can turn off the MDS feature but I don't want to resort to that.

    What I want is to simply change the word "Sites" from the suite links bar to "My Sites". Very simple DOM operation. 

    $('a#Sites_BrandBar span').text('My Sites'); So this is the code that should do it. It works when MDS feature is turned off.

    Here's what I've done

    In the <head> section I have the following

           

     <SharePoint:ScriptLink language="javascript" name="/~layouts/MyFeature.SP2016.Branding/scripts/jquery-3.1.1.min.js" LoadAfterUI="true" runat="server" Localizable="false" OnDemand="false" />
    
     <SharePoint:ScriptLink language="javascript" name="/~layouts/MyFeature.SP2016.Branding/scripts/myscript.js" LoadAfterUI="true" runat="server" Localizable="false" OnDemand="false"  />


    As per some of the articles I read including this one  you have to wrap the entire javascript.

    So my myscript.js looks like this

    function $_global_changeText() {
        $('a#Sites_BrandBar span').text('My Sites');
    }
    $_global_changeText();
    


    and the jQuery library has a wrapper around it as well.

    function $_global_jquery() {
    
    <original jQuery library here...>
    
    }
    $_global_jquery();


    That's all.

    when I look at the scripts that are loaded via the developer toolbar I don't even see my scripts in there.

    When am I doing wrong? Help please and thank you!


    Friday, December 02, 2016 11:02 PM

All replies

  • The problem with it is that when the Minimal Download Strategy feature is enabled, the JavaScript will only be run on the first page visit. Each return to the page will show the unmodified list or page without our customizations. There are two solutions: turn off the feature, or register our script. To register our script it must have a name. The example below replaces the anonymous function code with a normal named function. It includes two additional lines to register the function in the “do no ignore list” (my nickname for the list) and to call our function by name.

    // register our script
    RegisterModuleInit("/sites/yourSite/SiteAssets/CoolCode.js", MyCustomCode);
    
    // call our script
    MyCustomCode();
    
    function MyCustomCode() {
    
     //your code here
    
    }
    



     

    Mike Smith TechTrainingNotes.blogspot.com
    Books: SharePoint 2007 2010 Customization for the Site Owner, SharePoint 2010 Security for the Site Owner

    Saturday, December 03, 2016 3:43 AM
  • Thanks Mike

    Where exactly do I put the line below in the master page?

    // register our script
    RegisterModuleInit("/sites/yourSite/SiteAssets/CoolCode.js", MyCustomCode);


    Also when I call the script as you mentioned 

    // call our script MyCustomCode();

    Would this go in the body of the master page?
    Would I surround the code with scriptblock?

    <SharePoint:ScriptBlock runat="server" >
        MyCustomCode();
    </SharePoint:ScriptBlock>
    An full example would be great and much appreciated. I'm not that techical with javascript and I've been banging my head against the wall for a few days now.

    Thanks


    • Edited by The Profiler Saturday, December 03, 2016 4:32 AM
    Saturday, December 03, 2016 4:32 AM
  • I often add JavaScript using a Content Editor Web Part or JSLink, so the registration, the function and the call to it, can go just about anywhere. In a master page you usually load this in a script block in the header, or even at the end of the page just before the </body> tag.

    You will want to make sure that the page has fully loaded before trying to access SharePoint generated HTML.

    (The following is a copy/paste out of my SP 2010 customization book. While it mentions 2010, it still applies.)


    There are several possible solutions:

    • Put your script in a Content Editor Web Part and move it below all of the web parts that the script is changing
    • Put all of your scripts at or near the end of the page, but in SharePoint this would mean that they would have to be at the end of the master page
    • Wrap your code inside of a function and then run it with a JavaScript timer. But how do you know how long is not long enough and how long is too long?
    • Wrap your code inside of a function and then run it from the <BODY> tag's onload event - this works but again, this would need to be done from the master page

    The best solutions:

    The best way to run your JavaScript code is to insure that it runs after SharePoint has delivered all of its content to the browser. Here are several ways to do this:

    • Wrap your code inside of a function and then run it from SharePoint's own "script queue" (this is usually the best solution):

    function DoSomethingCool()

      {

        alert('page has loaded');

      }

    _spBodyOnLoadFunctionNames.push("DoSomethingCool");

     

    • Wrap your code inside of a jQuery "$(document).ready" function  (this works, but the above is probably a better choice as the .ready function does not wait until all of the SharePoint code runs):

    $(document).ready( function() {   alert('page has loaded');   } )

     

    The _spBodyOnLoadFunctionNames Array:

    "_spBodyOnLoadFunctionNames" is a JavaScript array created in the SharePoint master page and ".push" is a JavaScript method to add a new item to the end of the array. When a SharePoint page is loaded by a browser each function listed in this array is called in the order they were added, but only after the browser has completely loaded the page and run all of the SharePoint JavaScript.

    Notes:

    • Your function cannot use parameters - the following is not allowed:   mycoolfunction('abc')
    • The _spBodyOnLoadFunctionNames feature may change or go away in future versions of SharePoint, but works just fine in 2007 and 2010
    • The code that processes _spBodyOnLoadFunctionNames calls the functions in the order they are added; first in, first run
    • The jQuery "$(document).ready" will run your code as soon as all of the HTML has loaded, but without waiting for images and other linked files to load and may run the code before some of the SharePoint content has been loaded



    Mike Smith TechTrainingNotes.blogspot.com
    Books: SharePoint 2007 2010 Customization for the Site Owner, SharePoint 2010 Security for the Site Owner

    Saturday, December 03, 2016 2:12 PM