1,804 articles and 14,854 comments as of Wednesday, May 18th, 2011

EndUserSharePoint has combined resources with NothingButSharePoint.com. You can now find End User (Mark Miller), Developer (Jeremy Thake) and IT Pro SharePoint content all in one place!

This site is a historical archive and is no longer being updated. Please update your favorites, bookmarks and RSS feeds.

NothingButSharePoint.com
Monday, May 18, 2009

JQuery for Everyone: Faster than Document.Ready

Sometimes I want scripts to work as soon as possible, possibly even before document.ready.

For style changes, one option is to add CSS link or style tags to the page. However, if the CSS is tightly married to a JavaScript solution, it’s better to keep the styling changes based in JavaScript.

So here’s my approach: I wrote a jQuery plugin that dynamically adds SCRIPT and LINK tags to the page. That allows me to dynamically load JavaScript or CSS. The added benefit of this method, I utilize the browser’s cache as much as possible (editing web.config works even better if you have access) and all of the files are visible through Firebug as if they were loaded normally. That doesn’t happen when you load files using AJAX.

So, for my example, I want all of the submenu sections of my left nav to start closed, but only if jQuery loads and my other script to open and close those sections will run on document.ready.

preloaded css

As a result of this technique, the navigation behavior completely degrades (to a normal SP behavior) if any part of this does not load. But if it does load, the appearance is seamless to the user–you can’t see the sections contracting as the page loads.

Click “Read more…” to see the new plugin code and the example:

<!-- load jQuery from local library or src='http://ajax.googleapis.com/ajax/libs/jquery/1.3.1/jquery.min.js'-->
<script src="/javascripts/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript">/*
 * includeScript plugin
 * Copyright (c) 2009 Paul Grenier (endusersharepoint.com)
 * Licensed under the MIT (MIT-LICENSE.txt)
 */
(function($){
	var _debug = function(msg,type){
		if (window.console && window.console.log){
			if (!type){type="log";}
			console[type](msg);
			return true;
		}
		return false;
	};
	$.fn.includeFile = function(options, callback){
		var defaults = {"tag":"script",
						"url":"",
						"media":"screen",
						"rel":"stylesheet"
						},
			o = $.extend({},defaults,options),
			head = this[0],
			file = document.createElement(o.tag);
		switch (o.tag){
			case "script":
				file.src = o.url;
				file.type = o.type?o.type:"text/javascript";
				if (o.charset){file.charset=o.charset;}
				if (o.defer){file.defer="defer";}
				break;
			case "link":
				file.type = o.type?o.type:"text/css";
				file.rel = "stylesheet";
				file.href = o.url;
				file.media = "screen";
				if (o.target){file.target=o.target;}
				if (o.rev){file.rev=o.rev;}
				if (o.hreflang){file.hreflang=o.hreflang;}
				if (o.charset){file.charset=o.charset;}
				if (callback){_debug("not all browsers support callback for <"+o.tag+">","warn");}
				break;
			default:
				_debug("unknown tag: <"+o.tag+">","error");
				return $(this);
		}
 		file.onload = file.onreadystatechange = function(){
			if (!this.readyState || this.readyState == "loaded" || this.readyState == "complete"){
				if (callback && typeof callback=="function"){callback(o);}
				file.onload = file.onreadystatechange = null;
			}
		};
		head.appendChild(file);
		return $(this);
	};
})(jQuery);
//end plugin

//start instructions
$("head:first")
.includeFile({"url":"/javascripts/accordion-nav.js"},function(){
	$("head:first").includeFile({"tag":"link","url":"/javascripts/leftnav.css"}); //load the css file as a callback
})
.includeFile({"url":"/javascripts/expand-collapse-all.js"}) //another call chained from the first
.includeFile({"url":"/javascripts/ows.js"}); //end with semi-colon

//end instructions
</script>

Paul Grenier

View all entries in this series: PaulGrenier-JQuery for Everyone»
Entries in this series:
  1. JQuery for Everyone: Accordion Left Nav
  2. JQuery for Everyone: Print (Any) Web Part
  3. JQuery for Everyone: HTML Calculated Column
  4. JQuery for Everyone: Dressing-up Links Pt1
  5. JQuery for Everyone: Dressing-up Links Pt2
  6. JQuery for Everyone: Dressing-up Links Pt3
  7. JQuery for Everyone: Cleaning Windows Pt1
  8. JQuery for Everyone: Cleaning Windows Pt2
  9. JQuery for Everyone: Fixing the Gantt View
  10. JQuery for Everyone: Dynamically Sizing Excel Web Parts
  11. JQuery for Everyone: Manually Resizing Web Parts
  12. JQuery for Everyone: Total Calculated Columns
  13. JQuery for Everyone: Total of Time Differences
  14. JQuery for Everyone: Fixing Configured Web Part Height
  15. JQuery for Everyone: Expand/Collapse All Groups
  16. JQuery for Everyone: Preview Pane for Multiple Lists
  17. JQuery for Everyone: Preview Pane for Calendar View
  18. JQuery for Everyone: Degrading Dynamic Script Loader
  19. JQuery for Everyone: Force Checkout
  20. JQuery for Everyone: Replacing [Today]
  21. JQuery for Everyone: Whether They Want It Or Not
  22. JQuery for Everyone: Linking the Attachment Icon
  23. JQuery for Everyone: Aspect-Oriented Programming with jQuery
  24. JQuery for Everyone: AOP in Action - loadTip Gone Wild
  25. JQuery for Everyone: Wiki Outbound Links
  26. JQuery for Everyone: Collapse Text in List View
  27. JQuery for Everyone: AOP in Action - Clone List Header
  28. JQuery for Everyone: $.grep and calcHTML Revisited
  29. JQuery for Everyone: Evolution of the Preview
  30. JQuery for Everyone: Create a Client-Side Object Model
  31. JQuery for Everyone: Print (Any) Web Part(s) Plugin
  32. JQuery for Everyone: Minimal AOP and Elegant Modularity
  33. JQuery for Everyone: Cookies and Plugins
  34. JQuery for Everyone: Live Events vs. AOP
  35. JQuery for Everyone: Live Preview Pane
  36. JQuery for Everyone: Pre-populate Form Fields
  37. JQuery for Everyone: Get XML List Data with OWSSVR.DLL (RPC)
  38. Use Firebug in IE
  39. JQuery for Everyone: Extending OWS API for Calculated Columns
  40. JQuery for Everyone: Accordion Left-nav with Cookies Speed Test
  41. JQuery for Everyone: Email a List of People with OWS
  42. JQuery for Everyone: Faster than Document.Ready
  43. jQuery for Everyone: Collapse or Prepopulate Form Fields
  44. jQuery for Everyone: Hourly Summary Web Part
  45. jQuery for Everyone: "Read More..." On a Blog Site
  46. jQuery for Everyone: Slick Speed Test
  47. jQuery for Everyone: The SharePoint Game Changer
  48. JQuery For Everyone: Live LoadTip
 

Please Join the Discussion

9 Responses to “JQuery for Everyone: Faster than Document.Ready”
  1. Zuber Agwan says:

    “read more” does not work ?????

  2. Zuber – Sure does… just checked. How were you able to comment if the read more link didn’t work :-) – Mark

  3. AutoSponge says:

    There was a problem with the script, it got munched by Wordpress. Example should be visible now.

  4. Aaron says:

    Interested in checking this out – but maybe its a monday morning thing but I cant find a “read more” link on the page.

    Addtionally, where do you source the accordion-nav.js, leftnav.css, expand-collapse-all.js and ows.js files from?

  5. AutoSponge says:

    @Aaron,

    The link only shows when the page is viewed on the main page, as an individual article, the code is visible without clicking a link.

    The various scripts are just that. The only one I want to run ASAP (so users don’t see the collapsing action) is accordion left nav. See a similar script here:

    http://www.endusersharepoint.com/?p=1640

  6. Danno says:

    There seems to be an issue with this little jQuery plugin and Google’s Chrome browser. Here’s an example:

    I have the following page:

    Layout Example

    Center
    Go to the
    Demos page

    North
    South
    East
    West

    Simple.js contains the following:
    $(”head:first”).includeFile({”url”:”js/ui/jquery.layout.js”});
    $(document).ready(function () {
    $(’body’).layout({ applyDefaultStyles: true });
    });

    When I use the scriptLoader.js (my name for the above code), Chrome does not apply the layout. It
    seems to complain about ‘body’ not having a ‘layout’ method. IE and
    FF work with out error. If I move the jquery.layout.js include to a
    normal script tag in the html file (instead of having it be
    dynamically included), it works fine in all 3 browsers.

    Any idea what Chrome’s issue might be?

  7. AutoSponge says:

    @Danno,

    Document.ready only delays running the script until the document loads but it processes inline. When you called .layout, the layout.js file had not completely loaded.

    You must run the call to .layout after layout.js has loaded, so we use a callback function, like this:

    $("head:first").includeFile({"url":"js/ui/jquery.layout.js"},function () {
    $("body").layout({ applyDefaultStyles: true });
    });
    

    Since that anonymous function affects the DOM, we’ll still want to delay execution until the DOM loads, so you can wrap it in the document.ready (or equivalent):

    $("head:first").includeFile({"url":"js/ui/jquery.layout.js"},
    	$(function(){
    		$("body").layout({ applyDefaultStyles: true });
    	});
    );
    

    I haven’t tested this, but I hope it helps.

  8. Tom Hamshere says:

    A simpler solution might be to use a noscript tag to hide a noscript.css. This ensures the page is rendered correctly in browsers without JS and will not be loaded for those with JS. .


Notify me of comments to this article:


Speak and you will be heard.

We check comments hourly.
If you want a pic to show with your comment, go get a gravatar!