rickardnilsson.net is a weblog and the online home of web developer and father of three, Rickard Nilsson... More
Rickard blogs about creating software solutions using ASP.NET and agile practices.
It has been almost three years since I wrote my top ranking post on this blog: Applying stylesheets dynamically with jQuery. It was a quick and dirty example of a testing scenario pulled together for a colleague but it has become my number one linked post. It is still the post that gets the most hits every month because it is the first hit on Google for jquery add stylesheet which seems to be a lot of people has trouble with.
So, I felt it was time to do another post on the subject considering I’ve been using jQuery more or less every day these last three years.
I’ve created a simple jQuery plugin for adding or switching out stylesheets dynamically and interactively and it can be used like this:
<ul>
<li><a href="#" rel="1.css">Apply Stylesheet 1</a></li>
<li><a href="#" rel="2.css">Apply Stylesheet 2</a></li>
<li><a href="#" rel="3.css">Apply Stylesheet 3</a></li>
</ul>
$('a').click(function () {
$.stylesheets.clear().add($(this).attr('rel'));
return false;
});
$.stylesheets = (function () {
var stylesheets,
add,
clear;
add = function (cssfile) {
$('head').append('<link href="' + cssfile + '" rel="stylesheet" />');
return stylesheets;
};
clear = function () {
$('head link[rel=stylesheet]').remove();
return stylesheets = {
add: add,
clear: clear
} ());
Download source / demo
Why should you bother with combing and minifying JavaScript and CSS files? If you are a web developer working with sites with any significant traffic, you simply should because of the impact it will have on the load time of your site and how your visitors will perceive the page loading faster.
In the field of web site optimization, pioneered by Yahoo, there are many rules or guidelines which you should try to follow in hunt for milliseconds on the client side. In fact, it’s on the client that you will get the most value for your optimization work rather than on the server side [SOUDERS]. This is a subset of the rules regarding JavaScript and CSS.
I have searched for a tool that could help me implement many of the optimization guidelines and found a few worth taking a closer look at, one of these is the Google Closure Compiler. It has loads of features including file combining, minification, “compiling” your JavaScript into better JavaScript, as well as an API for loading your scripts asynchronously.
However, being a pragmatic .NET developer, I chose the most easily accessible tool available for me, which is Microsoft’s Ajax Minifier. It’s a free tool available on Codeplex and documentation is provided on the www.asp.net site.
Ajax Minifier comes as a command-line application and after you have installed it you can use it through it’s own command prompt.
Minifying a single JavaScript file is pretty straight forward. Simply type in the command prompt:
then add –clobber if you wish to override the outputfile.js if it exists, as in:
Minifying a single CSS file is equally simplistic as follows:
As before, add –clobber to override any existing output file.
Unfortunately there are no documentation on the asp.net site about how to combine multiple files into one, however, the ajaxmin command itself provides a hint given the /? parameter:
As an alternative to the input file parameter you can use the –xml parameter and supplying it with the path to an xml file of the following format:
<?xml version="1.0" encoding="utf-8"?>
<root>
<output path="outputfile.js">
<input path="inputfile1.js"/>
<input path="inputfile2.js"/>
<!-… ->
</output>
</root>
The Ajax Minifier will combine all of your input files into one, minify it, and produce the result in the output file. Using this approach you can also control in what order the files are loaded into the page and sort out any dependency issues, just as you would, had you listed includes in the regular html file (or .master or whatever).
The Ajax Minifier does not seem to have the smarts to deduce that this is JavaScript files so you need to supply it with a –js parameter like so:
I haven’t found a way to combine JavaScript and CSS in the same xml file so you need to make a separate file for you CSS files with the same format as above and instead of the –js parameter, use the –css dito:
Update follow up: jQuery plugin for switching stylesheets
A colleague of mine asked me how to apply a stylesheet to a web page dynamically using jQuery and I had never done such a thing but my first thought was that is must be pretty simple. I've spent a lot of time thinking of so many things other than web et. al. so it was nice to delve into some of that stuff again. Check out the live demo
As we know stylesheets are defined in the head section of an html file like this
<html>
<head>
<link rel="stylesheet" href="stylesheet.css" type="text/css" />
</head>
<body>
...
</html>
Now, say that we want to apply another stylesheet dynamically after the fact, so to speak, triggered by some event. This could be a button click or some other arbitrary event that is triggered. So, what we want to do is simply insert a new <link/> element into the head section of the page DOM. This can be done in a couple of lines of jQuery:
$(document).ready(function () {
$("a").click(function () {
$('head').append('<link rel="stylesheet" href="style2.css" type="text/css" />');
The key is at what time we add the link to the style sheet. The first line in the code above repeated here asserts that the DOM is ready for manipulation.
//...
The second part repeated here adds a click event to all hyperlinks in the page.
$("a").click(function() { //...
And the very task is performed by the last piece of code where the head element is appended with a new link element.
BlogEngine.NET ships with an extension that automatically highlights source code in blog posts. All that is required is that the source code block is surrounded with [code:lang][/code] tags. The extension will markup the code with CSS classes and the default theme includes a default color scheme for code elements like keywords, comments, and so forth. The extension ships with support for HTML, C#, JavaScript, T-SQL, MSH, and Visual Basic.
In forums and blogs in the BlogEngine community issues with the syntax highlighter extension has been brought up. Some of it can be found here, here, and here. Many has complained about how hard it is to use and lack of proper documentation. To get the tags to be recognized by the extension you have to format your post in a really precise manor with a leading and trailing <p></p>. Besides taking up a lot of unnecessary space when editing the post, this is why so many has complained that they can't get it to work. If the block is not correctly surrounded with the right amount of line breaks two things can happen. Either the whole code block is masked or the code is shown but the tags are rendered as part of the code block.
My own experience with this is pretty much the same and the only way to find out how it works was for me to read and step through the code. Since the extension is open source there is no hinder for improving the code base, hence I've been working to improve it to meet the community need, as well as my own. In addition to the mentioned usability issues I missed highlighting of types in C#, that is class, interface, and struct names which we are used to see in Visual Studio colored in cyan.
I'm about to present a new version of the extension which will include the following improvements:
Leave a comment on this post if you wish to be notified when the new version is available.
ICustomer customer = new Customer("kalle"); RegEx regex; ICollection<Customer> coll = new ICollection<Customer>(); Stack<Name.Space.Customer> stack = new Stack<Name.Space.Customer>(); stack.Put(customer); customer.Age = 24;
[Serializable] public class Customer : ICustomer , IComparable<ICustomer> { public Customer(string name) { this.name = name; person = new Person(name); } public int Age { get { return age; } set { age = value; } } IPerson _p = Person.CurrentUser; IPerson person; internal IPerson Person { get { return this.person; } }
private ShopingCart cart = new ShopingCart(); protected ShopingCart GetCart() { return cart; } }