During the last several months I have been doing more and more jQuery development and have found a few key tricks that have improved my code and made my development experience much more enjoyable.
1. Inject the jQuery library reference in the head section.
jQuery does not know about the DNNMenu and the ClientAPI. It will step all over them if given half a chance. Of course, DNNMenu and the ClientAPI are aware of possible conflicts with popular JavaScript libraries and will take steps to avoid any conflicts IF the jQuery library is already loaded. The ClientAPI is loaded at the top of the ASP.Net page form so loading jQuery in the header ensures it is loaded before the ClientAPI.
If you are building a module that injects a jQuery library reference, add it in the page header and you will be safe. If you just want to include a jQuery script on a page then you can edit the Page Settings/Advanced Settings to add the script reference to the Page Header Tags.
2. DotNetNuke 4.9.1 and above already include jQuery.
If you are using DNN 4.9.1 and above, then jQuery is already included in the distribution. The DNN 4.9.x versions will require you to add your own jQuery reference to the page, but DNN 5.x will add the reference to the page if the framework decides it is needed.
In 4.9.1+ you can either inject the jQuery using code or by using the Page Settings shown above. By default, DNN 4.9.x will use jQuery 1.2.6. If you require a newer version, then you should store your copy of the script in your module directory or in a portal directory. This will avoid some potential conflicts with other modules which may require a specific version of jQuery.
DNN 5.x will add jQuery to any page if the service is requested (see my previous jQuery post for the needed code). The DNN Widget framework, which is enabled by default, automatically registers every page. So as long as the widget framework is enabled, then you are covered. If not, have your module register the request or use the Page Settings shown above.
3. Don’t use the $ alias
One of the first things that a new jQuery user learns is the $ alias. Using $(selector) to get some page elements is a truly powerful concept. It is such a powerful concept that the $ alias is used by most of the major JavaScript frameworks. Since most of my work is in DotNetNuke, I find that it is just easier to avoid using the $ alias in my scripts. 5 extra characters seems a small price to pay for peace of mind. By staying away from the use of $ I have avoided a lot of problems.
For some people however the $ is an important feature of jQuery. Maybe they have existing scripts that they want to use and replacing all of the $ references would be too painful.
4. Wrap your jQuery in a closure to properly map the $ alias if you must use it.
For example the following jQuery code does not work in DotNetNuke:
$(function() {
$('#box span').hide();
$('#box').click(function() {
$('#box span').hide();
$('#box').css({'background-color': '#ccc'})
.animate({ left: 500 }, 2000)
.animate({ top: 150 }, 700, function() { $('#box').css({'background-color': '#988'}); })
.animate({ left: 0 }, 1200)
.animate({ top: 0 }, 700, function() {
$('#box span').show(1000, function() {
$('#box').css('background-color', '#333').css('color', '#fff');
});
});
});
});
Getting this function to work is easy – wrap the code in a simple function and pass the jQuery object as a parameter.
(function($) {
//Your jQuery code here
})(jQuery);
5. Variables are overrated
One of the greatest strengths of jQuery is that it allows you to chain method calls. Most methods in jQuery return a jQuery object. Using chaining allows you to minimize the creation of temporary variables which in turn makes your code easier to read.
There are still places where variables are useful. If you are creating multiple jQuery objects using the same selector or where you might be able to use a common ancestor element to get at the necessary elements, then you can gain a performance advantage by creating a temporary jQuery object and chaining subsequent method calls off that element.
Using a cached version of the jQuery object in the above script would result in:
$(function() {
var box = $("#box");
box.click(function() {
box.find('span').hide();
box.css({ 'background-color': '#ccc' })
.animate({ left: 500 }, 2000)
.animate({ top: 150 }, 700, function() { box.css({ 'background-color': '#988' }); })
.animate({ left: 0 }, 1200)
.animate({ top: 0 }, 700, function() {
box.find('span').show(1000, function() {
box.css('background-color', '#333').css('color', '#fff');
});
});
}).find('span').hide();
});
This script uses a single variable but avoids four calls to the jQuery constructor to create the same object, and chaining the find operation off this common element shouldn’t result in any performance degradation.
5. The End() function is your friend
The last example forced me to change the ordering from my original script and hide the span after creating the click event handler. Sometimes ordering is important so it is useful to know how to use a common jQuery element, modify descendents and then go back and modify the parent last. This is where the end function comes in. Essentially this function reverts the jQuery matched set to the list of elements prior to your previous destructive change. Using this technique, I can keep the same ordering in my code as the first example, and still make use of a common variable (yes I do know that I could create a second variable to cache the span object but then I wouldn’t be able to show you this example ;) ).
$(function() {
var box = $("#box");
box
.find('span')
.hide()
.end()
.click(function() {
box
.find('span')
.hide()
.end()
.css({ 'background-color': '#ccc' })
.animate({ left: 500 }, 2000)
.animate({ top: 150 }, 700, function() { box.css({ 'background-color': '#988' }); })
.animate({ left: 0 }, 1200)
.animate({ top: 0 }, 700, function() {
box.find('span').show(1000, function() {
box.css('background-color', '#333').css('color', '#fff');
});
});
});
});
6. Keep things lite
It is important to remember that all this JavaScript is not without a cost. There is a bandwidth cost to download the code to the client and there is an execution cost that the user also must pay. If you bloat up your page with too much JavaScript then it will affect the performance of the page for users running older machine or older web browsers. You should always keep the end user in mind when adding jQuery and JavaScript to the page because it has a double impact on your site performance. Just remember that in addition to your code, DotNetNuke is going to load the ClientAPI, the jQuery framework and the AJAX framework. That is a lot of JavaScript already on the page.
Where this becomes important is in the area of plugins. Often jQuery users will use a jQuery plugin because it has a lot of functionality, but if you are not using all of the functionality and you can reasonably code the needed functionality in a fraction of the code, then you are better rolling your own code and forgoing the use of the plugin. A great example of this is the jQuery UI tabs control. As I showed in my post How to create JQuery Tabs in DotNetNuke, you can build great looking tabs using very little JavaScript (about 23 lines of code plus 10 lines of CSS). Compare this with almost 13k of compressed code for the jQuery UI version of the tab control (plus 110K for the core jQuery UI library). Unless you really need all the functionality of the jQuery UI tabs and the UI library, then you are paying a huge price for very simple functionality.
Technorati Tags:
DotNetNuke,
jQuery