24 June 2008
Firefox 3
First off, I like the interface updates, the "awesome bar" and the speed improvements. I have been very impressed with its stability as well.
However, I have found difficulty using a number of plugins and in particular Firebug. This is simply unacceptable. I have tried using a number of different versions of Firebug but to no avail - all were slow and often crashed Firefox.
Whilst this has proven to be just about acceptable for working at home on things such as JSquared, at work it has proven utterly useless and I have downgraded to Firefox 2 and Firebug 1.05. The improvement in performance of Firebug was immense.
How are you finding Firefox 3 and Firebug? Have you found a combination that works for you?
9 June 2008
My JavaScript patterns
I use two main patterns, a singleton pattern and a constructor pattern. A singleton is an object which will have only one instance within an application. A constructor is a function which when invoked with the new keyword will create an object based on its definition. These objects are known as instances.
Constructor Pattern
A constructor pattern is something which JavaScript has native support for. Douglas Crockford has previously talked about this pattern at length.
function EventHandler() {
//constructor
//private members
var registeredEvents = [];
//public methods
this.registerHandler = function(func) {
if (typeof func === "function") {
registeredEvents.push(func);
}
}
this.fire = function() {
for (var i = registeredEvents.length-1; i >= 0; i--) {
registeredEvents[i]();
}
}
}
A constructor is simply a function which defines various members and contains its own variables and indeed other functions. You can also define constructor logic with a series of statements which do not declare methods or private variables or functions.
Its a fairly simple pattern and it is just as easy to use. To declare a new instance of this constructor, the code is simply this:
var myEventHandler = new eventHandler();
Singleton Pattern
My aim with a singleton is to have a highly readable object formation pattern which allows for private members and the exposure of a public interface. The syntax also must ensure that only one instance of the singleton can exist though of course there is nothing to stop the object being inherited from.
I also wanted the pattern to look similar to the constructor pattern above. This should make it easier to code and maintain.
For this example, I am using a simplified version of an object in JSquared. JSquared makes extensive use of this pattern as much of the library is built up from singleton objects. The object I am using here is the cookies object. For details on how to use this within an application of your own, look out for a post on the JSquared blog.
var cookies = new (function() {
//private members
var cookies = {};
//constructor
//get the current set of cookies
var currentCookies = document.cookie.split(";");
var cookie;
//loop through current cookies and add their values to the cookies collection
for (var i = currentCookies.length - 1; i >= 0; i--) {
cookie = currentCookies[i].split("=");
if (cookie.length >= 2) {
cookies[cookie[0]] = cookie[1];
}
}
//public methods
this.set = function(name, value, expiration) {
document.cookie = name + "=" + value + ";expires=" + expiration + ";path=/";
cookies[name] = value;
}
this.get = function(name) {
return cookies[name];
}
this.delete = function(name) {
this.set(name, "", -1);
delete cookies[name];
}
});
You will I am sure notice how similar this singleton pattern is to the constructor pattern above. The major difference is that the singleton pattern created the constructor as an anonymous function and then invoked an instance of that anonymous function immediately.
Just like when creating a new instance of a constructor, an object defined as per the constructor function will automatically be returned from the invocation. So in the example above, the variable cookies will contain the singleton.
The syntax may look odd, but it has proven itself very resilient and extremely effective. It allows for private members and functions, the public methods have access to those private members. It contains constructor logic and of course parameters can be passed in to the constructor just like they could be in the constructor pattern shown above.
As I seem to often say, its as simple as that!
27 May 2008
My JavaScript "rules"
None of this is meant to suggest that it cannot be improved. Nor am I saying that it is even that good! But, I thought it might be useful to talk about some of the ideas I have employed. These are my JavaScript "rules". I try to apply them in everything that I do:
1. Be unobtrusive
This is an absolutely imperative and key rule. Unobtrusive JavaScript code is easier to read, easier to write and is encapsulated within a JavaScript layer in your application. Writing unobtrusive code means having no JavaScript in the markup of your documents. Make use of browser events (onLoad, DOMContentLoaded etc) to apply the JavaScript enhancements to your pages. Use ID's and if necessary classes to pick DOM nodes from the document to work with.
2. Name your spaces
Namespaces make for much friendlier JavaScript. If nothing else, a namespace will stop you polluting the global scope of the document. I always have one root namespace for an application and then other namespaces off that to define the functionally different regions of your application. Always group similar functionality. If for example you have a bunch of objects which are used for handling forms and form validation, group them all under a common namespace. Creating a namespace is as easy as creating an object. Here is an example of creating a root namespace and 2 sub-namespaces:
var Nortools = {};
Nortools.Login = {};
Nortools.Forms = {};
3. Cry over spilt milk
I always encapsulate functionality within relevant objects and namespaces. Dont let that functionality spill out of the object or the namespace. Use private members in objects to hide the secrets of an object and strengthen your code. This will prevent your application from being changed or interfered with in any way by other JavaScripts on the page. I use self executing functions to create completely closed and hidden objects, neatly encapsulating my code. It is even possible to have private members on the prototype of a constructor using this technique:
var myConstructor = function() {};
myConstructor.prototype = new (function() {
var myPrivateMember = "some value";
this.getPrivateMemeber = function() {
return myPrivateMember;
}
});
This code may look odd, but the prototype of myConstructor is now a self creating singleton object which cannot be forced to give up its secrets. I use this technique for creating all singleton objects - its encapsulated!
4. Separate
I always separate the various types of code in my applications strictly. If I am dealing with data, I create a data layer to manage all that logic with as few public methods as possible. If I have business rules, the same applies. All presentation logic should also be self contained and independent of the data and the business rules which translate that data into objects which can then be displayed.
5. I object
Use objects and use them extensively. I never store any value within global scope and with everything in a well organised object model, you always know where things are. Use the singleton pattern above (or the many others which are just as good) to create singleton objects - an object that only has one instance.
6. JSON
JSON is extremely useful and powerful. I always use JSON for storing and transferring data in my applications. I also make extensive use of object notation for providing options to my objects. Passing in a JSON object to a constructor can be much easier than handling optional parameters. This is one method for handling optional parameters:
var myConstructor = function(param1, param2, param3) {
param1 = param1 || "defaultValue";
param2 = param2 || "defaultValue";
param3 = param3 || "defaultValue";
};
var myInstance = new myConstructor( "value", null, "value" );
With this method, on creating an instance, I have to know which parameter is which and what order they are in. Its also slightly clumsy looking.
My preferred method is:
var myConstructor = function(options) {
var param1 = options.param1 || "defaultValue";
var param2 = options.param2 || "defaultValue";
var param3 = options.param3 || "defaultValue";
};
var myInstance = new myConstructor( {
param2: "value",
param3: "value"
} );
Much neater and I find it much easier to understand and read.
7. Be a detective
I always try to code defensively. I dont want errors to even be possible in my code. To this end, I always want to detect whether the operation I am about to perform is possible. Sometimes this means checking my own objects for a feature, sometimes a built in object. This is much more effective than user agent sniffing for browser features. Not only do I not have to know what each specific browser supports, but I also do not have to keep changing my code each time there is a new version of a browser. It makes my code future proof!
if (document.getElementById) { //check the browser supports getElementById
var myElement = document.getElementById("myElement");
if (myElement) { //check an element was found
//perform some action
}
}
8. Lets go native
Always use native functionality when its there. Its the fastest method. If you want to have a getElementsByClassName function in your application, check if the browser already has it built in and use that method if it is there. Replacing it will only make your application slower.
9. Delegation's what you need
Events are very important when building web applications. But adding event handlers to lots of nodes can be bad for performance and lead to management overheads. If for instance you have a list of items and clicking on an item in the list performs an action, consider adding the click event to the parent of the list items and using a delegation pattern to handle the event. For a more detailed explanation see this excellent article.
10. Get organised
I always try to organise my code well. It is vital during a build phase of a project to be well organised. I only ever put one object or constructor in a JavaScript file and I name the file accordingly. If the full path (taking into account namespaces etc) to my object is MyApplication.ApplicationSection.ObjectName, then I will name the file MyApplication.ApplicationSection.ObjectName.js. In a large application, my folder structure will represent the namespace hierarchy as well.
Choose a coding style for your application and stick to it. I have my own coding style with naming conventions etc, and I always stick to it. It makes the code more consistent and easier to read and understand.
Comment code wherever it is needed to help understand why the code does what it does. Dont comment code when the comments will not add to the understanding of the code.
11. Dont panic
Writing JavaScript is hard. Writing web applications is harder still. Dont panic. Help is at hand. Use a library.
24 May 2008
JSquared 1.1 Beta 1
14 May 2008
Usability and accessibility
This thought has been focussed almost solely around two tasks. The first of these was an interesting proposition - to demonstrate that projects previously completed using Flash could be built using JavaScript. As a useful by-product, I have been able to make some more use of JSquared and particularly my alpha build of FXSquared!
There were two particular products that I have been looking at, the first of which was a finance tool for Fiat. I spent 2 days working on this task and as such was only able to make part of this tool.
I started by building the dials which are the main control for the tool. This involved building a number of animations and some simple interactions. I then worked on the panel which flashes as the values change. Amazingly, in only two days, I was able to match all the functionality of the dials and get the values updating in the panel and get the panel to flash.
Accessibility was not an important consideration however, when reviewing the work I was able to complete, the markup I had written was valid and semantic and the product fully accessible. It was certainly no less usable than the Flash, and due to the keyboard being able to control the tools, it was perhaps more usable. It was accessible and worked without CSS and could be made to work without JavaScript very simply. It was a triumph.
The other product I worked on, was in a similar vein and was a similar success.
The original project manager on the Fiat project could not tell the difference between the two products and it was entirely cross-browser.
The point I am making here is that by writing the tool using semantic HTML and progressively enhancing the code with CSS and JavaScript, I was able to make something more accessible and more usable all at the same time.
My second key experience was joining a project that had a significant development effort behind it already. I was asked to point out where I thought the product was not usable. I found myself pointing out 8 areas that I had issue with. When I took a step back and looked at these comments I realised how each of them could also have appeared on a list of changes to make the product more accessible!
These experiences have really driven home for me how closely linked accessibility and usability are and how investing in one will inevitably be investment in the other. What a great selling point for spending more effort on these vital areas that are sometimes overlooked by clients.
11 May 2008
The JSquared blog
From now on, this blog will discuss general web interface development issues whilst the JSquared blog will discuss features of JSquared and provide news of updates etc. You will see the latest few items in the left pane of this blog as well for convenience.
I have copied over the relevant posts to the JSquared blog. Please let me know if you have any comments.
8 May 2008
JSquared update
The big news however is that JSquared has a new home - www.j-squared.info. There will be a major update to the website to coincide with the release of JSquared 1.1 in late June or early July. JSquared will have its own blog, freeing this blog for non-JSquared related topics generally. More on that in time to come.
An update on the progress of the goals for release 1.1:
JSquared Testing Platform
Using JSUnit, I have had much success testing JSquared. I have about 20% code coverage in the core library so far. My aim is still to have full coverage of the core library for version 1.1
Documentation
Using JSDocs, I have documented around 40% of the core library and I am getting close to a full API reference. This will be available along with a quick start guide for JSquared 1.1
FXSquared
The core FX library is complete. It is based on plugins and I am working on two plugins. I have been using the FX library for a few weeks now and it is nearly ready for release. It will be released with JSquared 1.1
IE 8 Beta Support
There has been some work on general compatibility updates and JSquared continues to improve. It is unlikely that JSquared 1.1 will be fully tested and working on any beta platform, but there will be compatibility updates to help with IE 8 and Firefox 3 support as well as improved Opera 9.5 support.
I hope you are as excited as I am by these updates and new developments. JSquared work continues at a good pace (despite protests from my wife) and I am hoping to increase the usage of the library over the remainder of the year.
Just to keep you all excited, Chris Heilmann gave a talk at AKQA last week and he has posted about it.