Avoid using jQuery(document).ready

Description

Due specific SharePoint client side initialization life cycle, it is recommended to avoid using $(document).ready and windows.load = function() { ...};.

It is a common practice to modify content from JavaScript. The end user can't identify the moment when page has been changed, it looks like all page content rendered on server side. For example, SharePoint list views are used same approach named CSR.

$(document).ready used due to two reasons:
  1. run code AFTER DOM constructed
  2. run code BEFORE page rendered
Many times $(document).ready fires later than expected. Actually it handles DOMContentLoaded event. In case of static HTML content, DOMContentLoaded is raised right after content loaded from server(!) and before rendered. But SharePoint pages use JavaScript to build markup, offen when content is not loaded yet, thus it is unclear when the DOMContentLoaded event fires.

Resolution

We recommend to keep follow three rules:
  1. Use SP.SOD.executeOrDelayUntilScriptLoaded to manage scripts load order NOT depending on sharepoint .js file.
  2. Use SP.SOD.execute and SP.SOD.executeFunc to manage scripts load order depending on sharepoint .js file.
  3. Use arrays _spBodyOnLoadFunctionNames (sp2010) or _spBodyOnLoadFunctions (sp2013) to solve simple tasks on the SharePoint pages like list forms, views or web part pages. Be aware that content is often added after the page is loaded, for example: Web Parts in MDS, option tags in lookup fields, cascading lookups. Be sure you work with ready-to-proceed elements.
  4. In case of Minimal Download Strategy (MDS) use RegisterModuleInit function call to get your script loaded while asyc load occur.

window.myappName$ = window.myappName$ 
                    || jQuery.noConflict(true);
 
(function($) {
    if (!_spBodyOnLoadCalled) {
        _spBodyOnLoadFunctions.push(pageLoad);
    } else {
        pageLoad();
    }
 
    function pageLoad() {
        $('#pageTitle span').text('Hello from jQuery');
    }
 
    RegisterModuleInit(
            _spPageContextInfo.webServerRelativeUrl 
                + 'appname/script.js', 
            pageLoad);
})(window.myappName$);

How about mQuery?
m$.ready(function() {
 // DO STUFF
 });

In general mQuery does not play significant role and can't be consider as common solution. It uses onDemand load mode on many pages. That means it have to be used as

SP.SOD.execute("mquery.js", "m$.ready", function() { });

and expected running time will be too late ... defenitelly after content load/render.

Links

SharePoint 2010 and the Chrome JavaScript Bug
Getting started with mQuery/m$ in SharePoint 2013 and SharePoint Online
SharePoint Script On Demand (russian)
Применение mQuery в SharePoint 2013 (russian)
10 вещей, которые надо знать при использовании jQuery в SharePoint
Загрузка скриптов в SharePoint

Last edited Jul 29, 2014 at 11:27 AM by dvd73, version 28

Comments

HughAJWood Mar 18, 2014 at 7:58 PM 
To elaborate on this:

1) SharePoint 2013 in matter of fact uses CSR. This means the controls may not be ready on the page, and jquery .ready will not always pick this up. The correct place for this would be in the corresponding jslink file for ready state.

2) If you are running code that does not rely on the rendering of ASP.net controls, and it is specific to single page then consider use of the script manager script block. In this area it is now safe to use jquery ready() function in conjunction with SOD. Check the namespace of the desired javascript file first, then if it doesn't exist load your document ready code, else just run document ready. BIG NOTE: You cannot control the dependency order of the DOM with this method as some things are loaded via AJAX, jquery is not aware of these events, causing dependency collisions in some environements.

3) Specific usage of _spBodyOnLoadFunctions.push(function) is when you have ASP.net/SharePoint specific DOM dependencies. This includes all asp.net controls on the page. However there are known issues with certain builds of chrome that prevent it from working. http://mosswell.blogspot.co.uk/2013/06/sharepoint-2010-and-chrome-javascript.html