<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-8421903615286376978</id><updated>2012-01-20T20:43:47.554Z</updated><category term='Mobile'/><category term='FXSquared'/><category term='Twitter'/><category term='Usability'/><category term='jQuery'/><category term='CSS'/><category term='Conditional Comments'/><category term='Accessibility'/><category term='Progressive enhancement'/><category term='JSquared'/><category term='Opera'/><category term='AJAX'/><category term='ECMAScript'/><category term='CSS 3'/><category term='HTML 5'/><category term='JavaScript 2'/><category term='CSS reset'/><category term='Internet Explorer 8'/><category term='Browsers'/><category term='Google Chrome'/><category term='ADIJ'/><category term='off-topic'/><category term='Firefox'/><category term='Firebug'/><category term='Interface development'/><category term='Agile'/><category term='HTML'/><category term='Scrum'/><category term='Tools'/><category term='Process'/><category term='Internet Explorer'/><category term='JavaScript'/><category term='Browser support'/><category term='Web standards'/><category term='rant'/><title type='text'>Web Interface Development</title><subtitle type='html'>This is where you can find out all about interface development.&lt;br&gt;
Whats good, whats not good and most importantly, why!?</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://nortools.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://nortools.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>James Norton</name><uri>http://www.blogger.com/profile/04054375264545036477</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>69</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8421903615286376978.post-1077223345969192346</id><published>2009-11-19T14:32:00.002Z</published><updated>2009-11-19T14:44:40.221Z</updated><title type='text'>Building websites - how do you do it?</title><content type='html'>From reading the title of this post you might assume that I am about to talk about what I do every day and have always done.  You are only partly right.&lt;br /&gt;&lt;br /&gt;The specific topic I am interested in is the building of completely flat websites.  That is to say the type of delivery to a client which is made up of HTML, CSS and JavaScript that will never be integrated into a back-end, never have any other coding wrapped around it but will be kept as a series of flat pages.&lt;br /&gt;&lt;br /&gt;This is something I have had to do recently for the first time in some time and the question of how to achieve such a thing in an elegant manner keeping the trials of development to a minimum occupies some of my time now.&lt;br /&gt;&lt;br /&gt;What I did in this instance was use server side includes to include all the common components of each page from a central resource - this includes things like global navigation, a footer etc etc.  When it came time to send the code to the client, I then ran an ANT script (as supplied by the esteemed Mr Alexander, once more a colleague) to output the flat pages.&lt;br /&gt;&lt;br /&gt;This seemed to work well for me.  However, I was not happy with the way this worked for the CSS and JavaScript code.&lt;br /&gt;&lt;br /&gt;During development, I wanted the CSS and JavaScript code broken down into many files to help me find where code was, organise new code and bug fix.  I wanted the convenience of loading Firebug and being able to see exactly where my style declarations came from on any particular node.&lt;br /&gt;&lt;br /&gt;For the final delivery, I wanted one CSS file and just a few JavaScript files.  But how to make that happen without breaking my ideals during development?  Well, I could end up using ANT to piece it all together just like the HTML code.  But that felt a bit messy and frankly, hand crafting XML is about the worst thing I can think of doing.&lt;br /&gt;&lt;br /&gt;This is where I stop providing solutions and pose a question.  How would you have prepared your build?  How would you have made sure that during development you could pull in only the bits of JavaScript that should have been on each page and then built the flat files correctly?  Its more complex than it at first appears....&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8421903615286376978-1077223345969192346?l=nortools.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nortools.blogspot.com/feeds/1077223345969192346/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8421903615286376978&amp;postID=1077223345969192346' title='11 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/1077223345969192346'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/1077223345969192346'/><link rel='alternate' type='text/html' href='http://nortools.blogspot.com/2009/11/building-websites-how-do-you-do-it.html' title='Building websites - how do you do it?'/><author><name>James Norton</name><uri>http://www.blogger.com/profile/04054375264545036477</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>11</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8421903615286376978.post-6582718863677733709</id><published>2009-09-22T12:20:00.003+01:00</published><updated>2009-09-22T13:49:02.128+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='off-topic'/><title type='text'>Reflecting on a return to action</title><content type='html'>I have now been with my new employer - EMC Consulting - for four weeks and to be frank, I now have a lot more of interest to discuss on this blog.  So, I thought I would re start my posting here with some thoughts on these first four weeks.&lt;br /&gt;&lt;br /&gt;I have spent the last fourteen months working almost exclusively on a large and complex JavaScript application and I wont deny that I did learn quite a little bit during that time.  But I still find myself glad to be back working with all of my skills in a more balanced fashion.  Its been refreshing to see how much people care about UX and accessibility and it is a pleasure to be able to combine that with my passion for high quality and minimal CSS and HTML code.&lt;br /&gt;&lt;br /&gt;Already, pragmatism has reared its friendly head and is guiding my path.  This is something I have to reacquaint myself with and I am enjoying that process.  There is little to rival the feeling of writing code to fulfil a purpose, getting it done and working and moving on.&lt;br /&gt;&lt;br /&gt;Yes, I now have to fix IE6 bugs again, but at least I am able to do so in the shadow of Borough Market and the delights that can be found within!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8421903615286376978-6582718863677733709?l=nortools.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nortools.blogspot.com/feeds/6582718863677733709/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8421903615286376978&amp;postID=6582718863677733709' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/6582718863677733709'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/6582718863677733709'/><link rel='alternate' type='text/html' href='http://nortools.blogspot.com/2009/09/reflecting-on-return-to-action.html' title='Reflecting on a return to action'/><author><name>James Norton</name><uri>http://www.blogger.com/profile/04054375264545036477</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8421903615286376978.post-4663964611450329414</id><published>2009-08-10T13:48:00.004+01:00</published><updated>2009-08-10T14:11:24.792+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='JSquared'/><category scheme='http://www.blogger.com/atom/ns#' term='jQuery'/><title type='text'>jQuery browser history manager</title><content type='html'>Despite being the creator of &lt;a href="http://www.jsquaredjavascript.com"&gt;JSquared&lt;/a&gt;, I have recently had cause to use jQuery.&lt;br /&gt;&lt;br /&gt;For the project where it is in use, I needed a browser history manager and after a very rapid cursory search, none came up that caught my eye.  So, I decided to port my browser history manager from JSquared to jQuery and I woule like to make it available for you to use as well.&lt;br /&gt;&lt;br /&gt;It works like all other browser history managers, appending named items with a value onto the hash portion of the URL in a QueryString like format.&lt;br /&gt;&lt;br /&gt;The port is based on the new browser history manager that will be part of the next version of JSquared and it extends the jQuery object.  You can &lt;a href="http://jsquared.googlecode.com/files/browserhistorymanager.js"&gt;download it here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Using it could not be simpler.  You set up named items you wish to listen for changes on and provide a callback function for when the change occurs.  You can also update the value of an item as well.&lt;br /&gt;&lt;br /&gt;To listen for changes, simply do the following:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: Consolas; font-size: 10pt; color: black; background: #e1e1e1; padding: 10px;"&gt;&lt;pre style="margin: 0px;"&gt;$.url.listen( &lt;span style="color: #a31515;"&gt;&amp;quot;myItemName&amp;quot;&lt;/span&gt;, &lt;span style="color: blue;"&gt;function&lt;/span&gt;(e, itemValue, itemName) {&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;//perform some actions&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;});&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Your callback function will be called when the user goes back and forwards and the value of your named item changes.  The callback function will also get called if the user comes to your site from a bookmark and your item has a value.&lt;br /&gt;&lt;br /&gt;To update the value of an item and create an entry in the users history, just do the following:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: Consolas; font-size: 10pt; color: black; background: #e1e1e1; padding: 10px;"&gt;&lt;pre style="margin: 0px;"&gt;$.url.update( &lt;span style="color: #a31515;"&gt;&amp;quot;myItemName&amp;quot;&lt;/span&gt;, &lt;span style="color: #a31515;"&gt;&amp;quot;myNewValue&amp;quot;&lt;/span&gt;, &lt;span style="color: blue;"&gt;false&lt;/span&gt;);&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;The third parameter to the update method is called "dontUpdateUrl".  When set to true, the value shown to the user in the URL will not change, but the value internally within the browser history manager will.  This is useful is you are updating many items and only wish to create one history point.&lt;br /&gt;&lt;br /&gt;The new value can be any string and the object does not check that the length of the URL is safe - most browsers restrict URL's to around 2000 characters.&lt;br /&gt;&lt;br /&gt;Please do feedback on whether this is working well for you.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8421903615286376978-4663964611450329414?l=nortools.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nortools.blogspot.com/feeds/4663964611450329414/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8421903615286376978&amp;postID=4663964611450329414' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/4663964611450329414'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/4663964611450329414'/><link rel='alternate' type='text/html' href='http://nortools.blogspot.com/2009/08/jquery-browser-history-manager.html' title='jQuery browser history manager'/><author><name>James Norton</name><uri>http://www.blogger.com/profile/04054375264545036477</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8421903615286376978.post-2608792712888483634</id><published>2009-07-17T11:34:00.003+01:00</published><updated>2009-07-17T12:07:22.045+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='CSS'/><category scheme='http://www.blogger.com/atom/ns#' term='HTML'/><title type='text'>position:fixed</title><content type='html'>Well well, I have learnt something new this morning.  I think this new thing comes under the category of "how did I not already know this" but equally there is always the category of "kill IE6, please!".&lt;br /&gt;&lt;br /&gt;I suspect that had IE6 dies off a good few years ago, I would already know this new technique as it is not supported in IE6.  But I am very much of the opinion that we no longer need to support IE6 perfectly.  I do not want to go into detail about browser support, I have spoken often enough about my thoughts on the matter.&lt;br /&gt;&lt;br /&gt;So, onto the interesting part.  Have you ever wanted to create a layout with an element which has a height of 100% minus some pixels?  Or an equivalent for the width of an element?  I know that I have on many occasions.  Each time, I have had to either accept it cant be done or utilise some seemingly clever JavaScript to achieve my goal.&lt;br /&gt;&lt;br /&gt;But, no more!  position:fixed can now be our saviour.  Picture the situation where you have a two column layout with your navigation in the left column and content in the right column.  You want the left column to have a solid background colour and be 100% in height but leave a 50 pixel space at the top of the column.  You might use the following markup:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: Consolas; font-size: 10pt; color: black; background: #e1e1e1; padding: 10px;"&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;lt;!&lt;/span&gt;&lt;span style="color: #a31515;"&gt;DOCTYPE&lt;/span&gt; &lt;span style="color: red;"&gt;html&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;html&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;body&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;div&lt;/span&gt; &lt;span style="color: red;"&gt;id&lt;/span&gt;&lt;span style="color: blue;"&gt;=&amp;quot;LeftNavigation&amp;quot;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;ul&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ....a series of links&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;ul&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;div&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;div&lt;/span&gt; &lt;span style="color: red;"&gt;id&lt;/span&gt;&lt;span style="color: blue;"&gt;=&amp;quot;Content&amp;quot;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ....some content&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;div&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;body&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;html&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Now if you apply the following CSS:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: Consolas; font-size: 10pt; color: black; background: #e1e1e1; padding: 10px;"&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #a31515;"&gt;#LeftNavigation&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: red;"&gt;position&lt;/span&gt;:&lt;span style="color: blue;"&gt;fixed&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: red;"&gt;top&lt;/span&gt;:&lt;span style="color: blue;"&gt;50px&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: red;"&gt;bottom&lt;/span&gt;:&lt;span style="color: blue;"&gt;0&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: red;"&gt;background&lt;/span&gt;:&lt;span style="color: blue;"&gt;#cccccc&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: red;"&gt;overflow&lt;/span&gt;:&lt;span style="color: blue;"&gt;scroll&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;}&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="color: #a31515;"&gt;#Content&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: red;"&gt;margin-left&lt;/span&gt;:&lt;span style="color: blue;"&gt;310px&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="margin: 0px;"&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;You should see things exactly as I described above.  The key styles are on the LeftNavigation DIV, the position, top and bottom styles.  You should be aware that this is not supported in IE6 but I have found it works in all the browsers I have tried.&lt;br /&gt;&lt;br /&gt;If this is also new to you, have a little play - it has certainly brightened my day!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8421903615286376978-2608792712888483634?l=nortools.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nortools.blogspot.com/feeds/2608792712888483634/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8421903615286376978&amp;postID=2608792712888483634' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/2608792712888483634'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/2608792712888483634'/><link rel='alternate' type='text/html' href='http://nortools.blogspot.com/2009/07/positionfixed.html' title='position:fixed'/><author><name>James Norton</name><uri>http://www.blogger.com/profile/04054375264545036477</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8421903615286376978.post-1295641787034664786</id><published>2009-07-03T08:42:00.004+01:00</published><updated>2009-07-03T08:46:37.800+01:00</updated><title type='text'>Jamesnorton.com</title><content type='html'>I have launched my all new website at &lt;a href="http://www.jamesnorton.com "&gt;http://www.jamesnorton.com&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I wanted to get something out there to represent me and who I am and what I do, but the site is not complete.  It will move forwards and change and be enhanced over time.&lt;br /&gt;&lt;br /&gt;One thing you can all help me with is a potential Webkit bug particularly prevalent in Chrome but also an issue in Safari which I just cannot get to the bottom of.  If you view the site in a Webkit browser and you get weird large white patches at the bottom of the screen, please do reply to this post with details of which browser you are using.&lt;br /&gt;&lt;br /&gt;Otherwise, enjoy the site and feel free to provide any feedback you like.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8421903615286376978-1295641787034664786?l=nortools.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nortools.blogspot.com/feeds/1295641787034664786/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8421903615286376978&amp;postID=1295641787034664786' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/1295641787034664786'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/1295641787034664786'/><link rel='alternate' type='text/html' href='http://nortools.blogspot.com/2009/07/jamesnortoncom.html' title='Jamesnorton.com'/><author><name>James Norton</name><uri>http://www.blogger.com/profile/04054375264545036477</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8421903615286376978.post-1001168523392749946</id><published>2009-07-03T08:37:00.002+01:00</published><updated>2009-07-03T08:42:10.510+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Twitter'/><title type='text'>Macro to micro blogging</title><content type='html'>You will obviously have noticed the quiet on this blog over the past 6 weeks.&lt;br /&gt;&lt;br /&gt;Yes, its true, I have moved most of my activity onto Twitter now.&lt;br /&gt;&lt;br /&gt;I have neglected my blog.  I have found that I have a little less to say on here than I would like because I now only talk in units of 140 characters!  I would encourage you to &lt;a href="http://twitter.com/nortools"&gt;follow me on Twitter&lt;/a&gt; and that way you wont miss out!&lt;br /&gt;&lt;br /&gt;I will endeavour to make more updates to my blog, but I will always keep updating Twitter...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8421903615286376978-1001168523392749946?l=nortools.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nortools.blogspot.com/feeds/1001168523392749946/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8421903615286376978&amp;postID=1001168523392749946' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/1001168523392749946'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/1001168523392749946'/><link rel='alternate' type='text/html' href='http://nortools.blogspot.com/2009/07/macro-to-micro-blogging.html' title='Macro to micro blogging'/><author><name>James Norton</name><uri>http://www.blogger.com/profile/04054375264545036477</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8421903615286376978.post-2969016031429094601</id><published>2009-05-14T22:12:00.003+01:00</published><updated>2009-05-15T16:48:08.155+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Scrum'/><category scheme='http://www.blogger.com/atom/ns#' term='Agile'/><category scheme='http://www.blogger.com/atom/ns#' term='Process'/><title type='text'>Process</title><content type='html'>There is nothing like a discussion about process.  Everyone has their own ideas, every company works differently.&lt;br /&gt;&lt;br /&gt;I have recently taken a lot more interest in process.  Last month I became a Certified Scrum Master and those who know me will know that I am a Scrum advocate.  I think its a fantastic process.  I have worked on a couple of projects that used Scrum and it has proven itself to be very successful.&lt;br /&gt;&lt;br /&gt;Its a deceptively simple process which is far too often badly implemented.  A poor implementation of Scrum is more damaging than not using Scrum in my experience.&lt;br /&gt;&lt;br /&gt;I am not going to attempt to explain how Scrum works, I will leave that to the &lt;a href="http://en.wikipedia.org/wiki/Scrum_(development)"&gt;Wikipedia&lt;/a&gt;.  Whilst not the best explanation, it will suffice.  I personally enjoy using Scrum as it involves doing lots of small pieces of work which are well understood and can be fairly accurately estimated leading to reasonable expectations from clients and higher quality end product.  I also believe that the speed with which issues can be surfaced is a massive benefit.&lt;br /&gt;&lt;br /&gt;Doing Scrum badly will lead to more problems than if you were not doing Scrum at all.  It is for this reason that most Scrum trainers will suggest that until you are experienced at using Scrum and implementing it well, you should follow the Scrum process pretty much to the letter.&lt;br /&gt;&lt;br /&gt;A bad implementation of Scrum can force issues down and stop them being surfaced, can lead to inefficiencies as everyone attempts to work out what is going wrong and instead of opening up the process for all to see, it closes down the Scrum team and cloaks the detail in useless rhetoric.&lt;br /&gt;&lt;br /&gt;I want to work on projects using Agile with Scrum.  I do not want to be agile when I should be Agile nor vice-versa.  I make a distinction between agile and Agile and its an important one.&lt;br /&gt;&lt;br /&gt;When talking about agile with a lower case "a" I mean that I will show a more literal agility - responding to change, trying to prototype quickly and generally being flexible.  This is great for a client but dangerous.  Too much agility will lead to timelines slipping or the dreaded overtime!&lt;br /&gt;&lt;br /&gt;Agile with a capital "A" on the other hand is a process and a set of techniques including but not limited to Scrum and XP.  When I am being Agile, I will not respond to change in the same way, the person requesting the change has to follow a specific process, a simple process and one which is totally transparent.  I have never heard a client complain about having to do that when the result turns out to be a better product.  The process protects me and my Scrum team from being distracted, allowing quality to rise whilst also forcing the clients priorities to be my priorities.&lt;br /&gt;&lt;br /&gt;From this realisation I have chosen to be Agile not agile.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8421903615286376978-2969016031429094601?l=nortools.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nortools.blogspot.com/feeds/2969016031429094601/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8421903615286376978&amp;postID=2969016031429094601' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/2969016031429094601'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/2969016031429094601'/><link rel='alternate' type='text/html' href='http://nortools.blogspot.com/2009/05/process.html' title='Process'/><author><name>James Norton</name><uri>http://www.blogger.com/profile/04054375264545036477</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8421903615286376978.post-4769286797198518808</id><published>2009-05-14T12:58:00.002+01:00</published><updated>2009-05-22T11:19:23.339+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JSquared'/><title type='text'>JSquared 2.1</title><content type='html'>I am very pleased to announce that JSquared 2.1 has been released as of this morning.&lt;br /&gt;&lt;br /&gt;Check out &lt;a href="http://www.jsquaredjavascript.com"&gt;the website&lt;/a&gt; for yourself, follow the &lt;a href="http://blog.jsquaredjavascript.com"&gt;JSquared blog&lt;/a&gt;, &lt;a href="http://www.jsquaredjavascript.com/downloads.html"&gt;download the code&lt;/a&gt; and &lt;a href="http://www.jsquaredjavascript.com/docs/index.html"&gt;read the docs&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8421903615286376978-4769286797198518808?l=nortools.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nortools.blogspot.com/feeds/4769286797198518808/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8421903615286376978&amp;postID=4769286797198518808' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/4769286797198518808'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/4769286797198518808'/><link rel='alternate' type='text/html' href='http://nortools.blogspot.com/2009/05/jsquared-21.html' title='JSquared 2.1'/><author><name>James Norton</name><uri>http://www.blogger.com/profile/04054375264545036477</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8421903615286376978.post-7371872212479698178</id><published>2009-04-24T22:48:00.002+01:00</published><updated>2009-04-24T22:55:02.953+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Scrum'/><category scheme='http://www.blogger.com/atom/ns#' term='JSquared'/><category scheme='http://www.blogger.com/atom/ns#' term='off-topic'/><title type='text'>Recent times</title><content type='html'>I am sure you will have noticed that posting has been light on here the last few weeks and I thought it might be interesting to talk a little about what I have been doing.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I have spent most of my spare time working on JSquared.  The code base is coming on nicely now.  I have completely re-written some parts of it even since the latest release and I am getting close to being code complete for the next version.  Some more demos will come soon as well, but you can get more information on that over on the JSquared blog over the coming week or two.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Recently I have achieved the status of Certified Scrum Master.  This is something about which I am very excited.  I believe that Agile with Scrum is a fantastic engineering process.  I have seen it in action myself whilst I worked at LBi and I am actively looking to assist Betfair in making the transition to this process.  It can be painful and without doubt we are not yet getting it right, but with time, I am sure we will.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now that I am officially certified, I feel more able to push things forward with Betfair and I have gained a great understanding of the process.  I even think that I might bring some of the principles to my "normal" life, though I am not sure my wife will like a daily scrum meeting!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Hopefully I should be able to work on some more exciting things over the coming months than in the last few and I will be sure to blog about any and all the exciting happenings in the world of Betfair.  For now, it seems I am far more an observer than participant in this great interface development world in which I live and work.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8421903615286376978-7371872212479698178?l=nortools.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nortools.blogspot.com/feeds/7371872212479698178/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8421903615286376978&amp;postID=7371872212479698178' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/7371872212479698178'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/7371872212479698178'/><link rel='alternate' type='text/html' href='http://nortools.blogspot.com/2009/04/recent-times.html' title='Recent times'/><author><name>James Norton</name><uri>http://www.blogger.com/profile/04054375264545036477</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8421903615286376978.post-775530320671016633</id><published>2009-04-05T18:12:00.003+01:00</published><updated>2009-04-05T18:18:15.136+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='JSquared'/><category scheme='http://www.blogger.com/atom/ns#' term='FXSquared'/><title type='text'>JSquared 2.0</title><content type='html'>For those of you that might have missed the news, I released JSquared 2.0 today, April 5 2009.&lt;br /&gt;&lt;br /&gt;This version represents a massive step forwards for the library.  There is a whole new website to go along with the massively revamped code base.  The documentation has become much more extensive and the website now features demos of how some of the library works.&lt;br /&gt;&lt;br /&gt;The best thing to do is to check out &lt;a href="http://www.jsquaredjavascript.com"&gt;the website&lt;/a&gt; for yourself, follow the &lt;a href="http://blog.jsquaredjavascript.com"&gt;JSquared blog&lt;/a&gt;, &lt;a href="http://www.jsquaredjavascript.com/downloads.html"&gt;download the code&lt;/a&gt; and &lt;a href="http://www.jsquaredjavascript.com/docs/index.html"&gt;read the docs&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8421903615286376978-775530320671016633?l=nortools.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nortools.blogspot.com/feeds/775530320671016633/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8421903615286376978&amp;postID=775530320671016633' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/775530320671016633'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/775530320671016633'/><link rel='alternate' type='text/html' href='http://nortools.blogspot.com/2009/04/jsquared-20.html' title='JSquared 2.0'/><author><name>James Norton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8421903615286376978.post-2283838599629784683</id><published>2009-04-02T12:56:00.003+01:00</published><updated>2009-04-02T13:26:11.877+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rant'/><category scheme='http://www.blogger.com/atom/ns#' term='Internet Explorer'/><category scheme='http://www.blogger.com/atom/ns#' term='Browser support'/><category scheme='http://www.blogger.com/atom/ns#' term='Browsers'/><title type='text'>IE6</title><content type='html'>IE6 is a browser that all web developers hate.  Or at least that is the case if you tow the line.  &lt;br /&gt;&lt;br /&gt;IE6 used to be by far the most common browser and once was the most advanced.  However, things have moved on since 2001.  Web developers hate IE6 for its poor implementation of standards.  Web developers hate the vagaries of the IE6 rendering engine and the performance of its JavaScript engine.  These problems are well documented elsewhere.&lt;br /&gt;&lt;br /&gt;However, the important people, the ones who matter, the ones who web developers do all their hard work for - the users - they don't seem to care nearly as much.  This can be evidenced by the proportion of users who still use IE6.  Even today, 8 years after its launch, over 15% of users typically visit a website with IE6.  If I were Microsoft, I might just be congratulating myself for making a product so beloved of its users.  Of course, where I to do that then I would naively be ignoring the massive proportion of users who have no idea what browser they are using, that there are other browers out there or how to switch.&lt;br /&gt;&lt;br /&gt;We as web developers must also not ignore this set of users.  There have been a lot of campaigns started recently to end IE6 support.  Some have gone even further such as &lt;a href="http://www.wait-till-i.com/2009/04/02/easing-the-transition-from-ie6-to-using-newer-browsers/"&gt;this one I just came across&lt;/a&gt;.  I support the idea of getting our users using a more modern browser, but its up to them not us.&lt;br /&gt;&lt;br /&gt;I don't get the big deal here.  I stopped treating IE6 as a "fully supported browser" about 2 years ago.  I think the problem here is this idea that a website must look identical in all supported browsers.  What is wrong with a website looking subtly different in different browsers?  &lt;br /&gt;&lt;br /&gt;Of all the websites I have built from scratch in the last 2 years, not one has looked identical in different browsers unless it has been demanded from the client.  They all worked in an identical way, but they looked subtly different - generally because browsers have different default rendering styles.&lt;br /&gt;&lt;br /&gt;These differences have never been an issue. In IE6 you might get simpler button styles, you might get a more linear visual layout or you might find text looking slightly different.  When I have shown them to a client and explained why they are different, the client does not care either - in fact they are thankful for the money and time saved!&lt;br /&gt;&lt;br /&gt;I have only had problems with IE6 when I have been maintaining a site where the client has it in writing that browser support will include IE6 and that the site will be identical in all browsers.  &lt;br /&gt;&lt;br /&gt;In the many many demonstrations to clients that I have made in the last 2 years, I have never once been asked to use any browser other than the one I picked for the demo.  &lt;br /&gt;&lt;br /&gt;So, I just don't get the big deal with IE6 these days.  Lets make a big deal about why we need to make websites look identical in different browsers on different platforms.  Lets make a big deal about making websites more accessible.  Lets make a big deal about building standards compliant websites with the simplest possible code.  &lt;br /&gt;&lt;br /&gt;If we spend our energies doing this, then we are more likely to have built-in zero cost support for many many browsers including mobile browsers, not just a narrow set often defined well before the release of a website and therefore out of date at its release.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8421903615286376978-2283838599629784683?l=nortools.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nortools.blogspot.com/feeds/2283838599629784683/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8421903615286376978&amp;postID=2283838599629784683' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/2283838599629784683'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/2283838599629784683'/><link rel='alternate' type='text/html' href='http://nortools.blogspot.com/2009/04/ie6.html' title='IE6'/><author><name>James Norton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8421903615286376978.post-7877266513187837701</id><published>2009-04-01T23:16:00.004+01:00</published><updated>2009-04-02T10:03:49.354+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JSquared'/><title type='text'>CSS Selector Engines</title><content type='html'>CSS selectors are a great way to pick DOM nodes off a page and many JavaScript libraries use them extensively.&lt;br /&gt;&lt;br /&gt;For those that have used JSquared, you will know that there is no CSS selector engine built in.  Some people have asked why and I have always said that I think its simpler, faster, easier and makes a better performing application to use standard DOM methods to pick elements.&lt;br /&gt;&lt;br /&gt;Well, yesterday I saw &lt;a href="http://dante.dojotoolkit.org/taskspeed/"&gt;TaskSpeed&lt;/a&gt; and it got me thinking.  I was about to start making a JSquared version of the tests in order to see what the performance was when I cam across &lt;a href="http://webreflection.blogspot.com/2009/04/taskspeed-dom-vs-libraries.html"&gt;this post&lt;/a&gt; which proved the point I wanted to make without me having to do any work!&lt;br /&gt;&lt;br /&gt;Andrea shows that using native DOM methods is by far and away the fastest way to complete the tests.  Whilst this isn't totally related to a CSS selector engine, it does show that native methods are the best and that certainly holds true for the few parts of the test where a selector engine would be used it it existed.&lt;br /&gt;&lt;br /&gt;Of course, once all browsers in use support the Selectors API, all will be much improved,&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8421903615286376978-7877266513187837701?l=nortools.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nortools.blogspot.com/feeds/7877266513187837701/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8421903615286376978&amp;postID=7877266513187837701' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/7877266513187837701'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/7877266513187837701'/><link rel='alternate' type='text/html' href='http://nortools.blogspot.com/2009/04/css-selector-engines.html' title='CSS Selector Engines'/><author><name>James Norton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8421903615286376978.post-2724002495478139574</id><published>2009-03-31T22:54:00.002+01:00</published><updated>2009-03-31T22:59:19.356+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tools'/><category scheme='http://www.blogger.com/atom/ns#' term='off-topic'/><title type='text'>What do you use?</title><content type='html'>Every now and then I like to play with some new tools.  Try a few Firefox plugins, maybe a new dev environment.  This week is one of those times.&lt;br /&gt;&lt;br /&gt;So make your recommendations, what do you use that is cool and why?&lt;br /&gt;&lt;br /&gt;Just to get things started and to pre-emptively give something back, I have recently been playing with &lt;a href="https://www.spotify.com/"&gt;Spotify&lt;/a&gt; which I can recommend as a great way to listen to some new and old music.  &lt;br /&gt;&lt;br /&gt;I have also been playing with &lt;a href="https://addons.mozilla.org/en-US/firefox/addon/9954"&gt;XUL Profiler&lt;/a&gt; which is a pretty cool Firefox plugin (a nightly of Minefield works best with it I believe) for profiling your JavaScript and analysing how much work the browser is doing to render your page.&lt;br /&gt;&lt;br /&gt;Now its your turn...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8421903615286376978-2724002495478139574?l=nortools.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nortools.blogspot.com/feeds/2724002495478139574/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8421903615286376978&amp;postID=2724002495478139574' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/2724002495478139574'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/2724002495478139574'/><link rel='alternate' type='text/html' href='http://nortools.blogspot.com/2009/03/what-do-you-use.html' title='What do you use?'/><author><name>James Norton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8421903615286376978.post-9107039674159022793</id><published>2009-03-25T11:27:00.003Z</published><updated>2009-03-25T11:29:02.849Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Twitter'/><category scheme='http://www.blogger.com/atom/ns#' term='off-topic'/><title type='text'>Twitter</title><content type='html'>Twitter is something I never looked at until very recently and for some reason I have suddenly decided to use!&lt;br /&gt;&lt;br /&gt;So rather excitingly, I am now on Twitter and you can follow my antics (or whatever I bother to say on there) at &lt;a href="http://twitter.com/nortools"&gt;http://twitter.com/nortools&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I hope you have as much as fun reading as I do writing.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8421903615286376978-9107039674159022793?l=nortools.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nortools.blogspot.com/feeds/9107039674159022793/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8421903615286376978&amp;postID=9107039674159022793' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/9107039674159022793'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/9107039674159022793'/><link rel='alternate' type='text/html' href='http://nortools.blogspot.com/2009/03/twitter.html' title='Twitter'/><author><name>James Norton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8421903615286376978.post-4056177601437122601</id><published>2009-03-17T09:25:00.004Z</published><updated>2009-03-17T09:40:05.408Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Internet Explorer'/><category scheme='http://www.blogger.com/atom/ns#' term='Internet Explorer 8'/><title type='text'>IE8 - right, wrong or something else...?</title><content type='html'>For those that don't know I was recently struck down by a rather severe bout of bronchitis which has laid me low for 3 full weeks.  I am delighted to say that I am almost fully recovered.  Though just to be sure, I am still "taking the pills" - a form of prevention as much as cure.&lt;br /&gt;&lt;br /&gt;Its amazing how similar that situation is when compared to Internet Explorer.&lt;br /&gt;&lt;br /&gt;For many years, IE was suffering from an infection - non-standards compliance.  There was a lack of anti-bodies to kill it off.  But Microsoft finally took its sick child to the doctor who prescribed a welcome initial course of anti-biotics and so IE7 was born.  But all was not fully well, so a second course was required.&lt;br /&gt;&lt;br /&gt;As Microsoft now force-feeds its child the last dose of that medicine, we see IE8 emerge.  Standards compliant, much improved performance and an all round more open approach to development.&lt;br /&gt;&lt;br /&gt;But the virus remains, dormant for some but nonetheless very real and there.  It has mutated into compatibility mode.  Luckily there is a vaccination, a form of prevention, and that is a valid doctype and standards compliance.&lt;br /&gt;&lt;br /&gt;Of course, you could stop reading the drivel I am writing and &lt;a href="http://www.theregister.co.uk/2009/03/17/opera_ceo_microsoft/"&gt;read about what Jon von Tetzchner from Opera thinks of IE8&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Whatever you think of Microsoft and IE, you have to acknowledge that they are trying.  They cannot please everyone and certainly the remaining prevalence of IE6 does not please me, but I do believe they are trying.  Now if only they could speed up their release schedules, I could finally breathe easy.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8421903615286376978-4056177601437122601?l=nortools.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nortools.blogspot.com/feeds/4056177601437122601/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8421903615286376978&amp;postID=4056177601437122601' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/4056177601437122601'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/4056177601437122601'/><link rel='alternate' type='text/html' href='http://nortools.blogspot.com/2009/03/ie8-right-wrong-or-something-else.html' title='IE8 - right, wrong or something else...?'/><author><name>James Norton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8421903615286376978.post-3762615306898378478</id><published>2009-03-16T17:21:00.003Z</published><updated>2009-03-16T17:29:35.783Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Web standards'/><category scheme='http://www.blogger.com/atom/ns#' term='HTML'/><category scheme='http://www.blogger.com/atom/ns#' term='HTML 5'/><title type='text'>Standards - again</title><content type='html'>As if to reinforce what &lt;a href="http://nortools.blogspot.com/2008/11/standards.html"&gt;I was saying 4 months&lt;/a&gt;, the unique and unparalleled Douglas Crockford has articulated in part my own thoughts about HTML 5 in &lt;a href="http://blog.360.yahoo.com/blog-TBPekxc1dLNy5DOloPfzVvFIVOWMB0li?p=978"&gt;this blog post&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;As I said back in November:&lt;br /&gt;&lt;q&gt;I want to see greater interoperability between the various browsers and as such I believe simplification would be better.&lt;/q&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8421903615286376978-3762615306898378478?l=nortools.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nortools.blogspot.com/feeds/3762615306898378478/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8421903615286376978&amp;postID=3762615306898378478' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/3762615306898378478'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/3762615306898378478'/><link rel='alternate' type='text/html' href='http://nortools.blogspot.com/2009/03/standards-again.html' title='Standards - again'/><author><name>James Norton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8421903615286376978.post-2821291889847181702</id><published>2009-02-16T22:47:00.002Z</published><updated>2009-02-16T23:08:50.729Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Interface development'/><category scheme='http://www.blogger.com/atom/ns#' term='Progressive enhancement'/><category scheme='http://www.blogger.com/atom/ns#' term='CSS'/><title type='text'>Changing style regarding changing style</title><content type='html'>I was having a conversation with the esteemed Mr Alexander today about changing CSS styles based on whether JavaScript is enabled in the users browser.&lt;br /&gt;&lt;br /&gt;This problem had consumed some of my thoughts in the past and eventually I chose to use the technique I termed progressive degradation, something I have blogged about in a &lt;a href="http://nortools.blogspot.com/2008/03/progressive-degradation.html"&gt;previous post&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Progressive degradation involves writing your CSS with the assumption that JavaScript is enabled.  You then include an additional style sheet in this way:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: Consolas; font-size: 10pt; color: black; background: #e1e1e1; padding:10px;"&gt;&lt;p style="margin: 0px; margin: 0;"&gt;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;noscript&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px; margin: 0;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;link&lt;/span&gt; &lt;span style="color: red;"&gt;rel&lt;/span&gt;&lt;span style="color: blue;"&gt;="stylesheet"&lt;/span&gt; &lt;span style="color: red;"&gt;href&lt;/span&gt;&lt;span style="color: blue;"&gt;="noscript.css"&lt;/span&gt; &lt;span style="color: red;"&gt;type&lt;/span&gt;&lt;span style="color: blue;"&gt;="text/css"&lt;/span&gt; &lt;span style="color: red;"&gt;media&lt;/span&gt;&lt;span style="color: blue;"&gt;="screen"&lt;/span&gt; &lt;span style="color: blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px; margin: 0;"&gt;&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;noscript&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;This has generally worked well for me with the one caveat that this is invalid HTML.  This has concerned me a little.  The argument which both myself and Mr Alexander have used is that this is easily the simplest way to adjust styles depending on whether JavaScript is enabled or not.&lt;br /&gt;&lt;br /&gt;I prefer to write my CSS with the assumption that the best possible experience is available and then include CSS to enhance the experience for those users with a less capable user agent as required.&lt;br /&gt;&lt;br /&gt;Mr Alexander proposed another potentially neat solution:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: Consolas; font-size: 10pt; color: black; background: #e1e1e1; padding:10px;"&gt;&lt;p style="margin: 0px; margin: 0;"&gt;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;link&lt;/span&gt; &lt;span style="color: red;"&gt;rel&lt;/span&gt;&lt;span style="color: blue;"&gt;="stylesheet"&lt;/span&gt; &lt;span style="color: red;"&gt;href&lt;/span&gt;&lt;span style="color: blue;"&gt;="noscript.css"&lt;/span&gt; &lt;span style="color: red;"&gt;type&lt;/span&gt;&lt;span style="color: blue;"&gt;="text/css"&lt;/span&gt; &lt;span style="color: red;"&gt;media&lt;/span&gt;&lt;span style="color: blue;"&gt;="screen"&lt;/span&gt; &lt;span style="color: red;"&gt;id&lt;/span&gt;&lt;span style="color: blue;"&gt;="noScriptCSS"&lt;/span&gt; &lt;span style="color: blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px; margin: 0;"&gt;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;script&lt;/span&gt; &lt;span style="color: red;"&gt;type&lt;/span&gt;&lt;span style="color: blue;"&gt;="text/javascript"&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px; margin: 0;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; noScriptCSS = document.getElementById(&lt;span style="color: #a31515;"&gt;"noScriptCSS"&lt;/span&gt;);&lt;/p&gt;&lt;p style="margin: 0px; margin: 0;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; noScriptCSS.parentNode.removeChild(noScriptCSS);&lt;/p&gt;&lt;p style="margin: 0px; margin: 0;"&gt;&lt;span style="color: blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;script&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;In this example, the noscript CSS file is always in the document and it is then removed using JavaScript immediately.  I haven't tested this, but my first thought was that I would need to investigate if there would be a flicker on the screen as the page is reflowed, affecting the rendering performance of the page.  My second thought is that this technique involves an additional HTTP request for all users not only those who need it.&lt;br /&gt;&lt;br /&gt;There is another well known technique which involves writing your CSS assuming that JavaScript is not available and then including a script enabled CSS file using JavaScript as the page is being rendered.  I am not a fan of this technique as I prefer not to write my CSS in this way. &lt;br /&gt;&lt;br /&gt;There are a variety of other techniques as well such as changing a class on the BODY tag using JavaScript and cascading your selectors from that.  If using this technique I would always have a noscript class on the BODY and then remove that (again, it fits better with the way I like to write my CSS).&lt;br /&gt;&lt;br /&gt;This issue often raises its head and frankly I am now not fully satisfied with any of these techniques.  So what do you think?  What is the best way of handling this issue?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8421903615286376978-2821291889847181702?l=nortools.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nortools.blogspot.com/feeds/2821291889847181702/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8421903615286376978&amp;postID=2821291889847181702' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/2821291889847181702'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/2821291889847181702'/><link rel='alternate' type='text/html' href='http://nortools.blogspot.com/2009/02/changing-style-regarding-changing-style.html' title='Changing style regarding changing style'/><author><name>James Norton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8421903615286376978.post-4897037483966144158</id><published>2009-01-20T14:56:00.002Z</published><updated>2009-01-20T15:08:08.363Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Conditional Comments'/><category scheme='http://www.blogger.com/atom/ns#' term='Internet Explorer'/><category scheme='http://www.blogger.com/atom/ns#' term='Browser support'/><category scheme='http://www.blogger.com/atom/ns#' term='Browsers'/><category scheme='http://www.blogger.com/atom/ns#' term='JSquared'/><title type='text'>Browser detection</title><content type='html'>I am not a fan of user agent sniffing.  I think it is a wholly inappropriate way to find out the capabilities of a user agent accessing your website.&lt;br /&gt;&lt;br /&gt;However, it has its uses.  Steve Souders built &lt;a href="http://stevesouders.com/ua/"&gt;UA Profiler&lt;/a&gt;, for gathering browser performance characteristics.  This is undoubtedly an important and intriguing project.  In order to detect which browser you are using, he has written his own user agent sniffing code as he describes in &lt;a href="http://www.stevesouders.com/blog/2009/01/18/user-agents-in-the-morning/"&gt;his latest blog post&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;He also offers to make this code available through a web service.  This is an intriguing possibility.  My first reaction was to think that this was an excellent move.  A high quality user agent sniffer, improved upon by the community and its breadth of use that we could all access via a web service meaning we would not have to ask our users to download the code to do the detection.&lt;br /&gt;&lt;br /&gt;Having calmed down slightly, I started to think more clearly.  Overall, I am not convinced this is the best idea.  Generally I feel that detecting a user agent from its user agent string is dangerous.  This makes the assumption that no user agent spoofing is taking place, that your detection is granular and perfect enough and that browser features and support will not change.  None of these are necessarily true.&lt;br /&gt;&lt;br /&gt;I prefer to use feature detection.  If I want to know whether the browser I am using is capable of applying a particular method, does that method exist?&lt;br /&gt;&lt;br /&gt;The only reliable way I have found to detect a browser is for Internet Explorer only using conditional comments, both in HTML (useful for including CSS and JavaScript files for specific versions of IE) and in the JavaScript itself.&lt;br /&gt;&lt;br /&gt;I notice that the latest version of jQuery (1.3) is deprecating its user agent sniffing.  This decision is to be applauded.&lt;br /&gt;&lt;br /&gt;I also realised that the next version of JSquared will actually add the ability to determine if the browser you are using is IE and if it is version 6 or another version.  Whilst I might be adding a limited set of user agent support to my library, I am trying to do it in a fail-safe way.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8421903615286376978-4897037483966144158?l=nortools.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nortools.blogspot.com/feeds/4897037483966144158/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8421903615286376978&amp;postID=4897037483966144158' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/4897037483966144158'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/4897037483966144158'/><link rel='alternate' type='text/html' href='http://nortools.blogspot.com/2009/01/browser-detection.html' title='Browser detection'/><author><name>James Norton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8421903615286376978.post-1176264153730656322</id><published>2009-01-07T12:40:00.003Z</published><updated>2009-01-08T14:25:20.050Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='CSS 3'/><category scheme='http://www.blogger.com/atom/ns#' term='Browser support'/><category scheme='http://www.blogger.com/atom/ns#' term='Progressive enhancement'/><category scheme='http://www.blogger.com/atom/ns#' term='CSS'/><title type='text'>Using CSS3</title><content type='html'>Despite ones personal feelings about it, I am really keen to start using CSS3.  There are a number of browsers with support for some of the interesting parts of CSS3 and I think there is a new opportunity to use our skills of progressive enhancement to create some really exciting new effects.&lt;br /&gt;&lt;br /&gt;If we wisely apply the appropriate properties, we can enhance the user experience for some users - and an increasing number of users - whilst offering a more than acceptable experience for the remainder of our users.&lt;br /&gt;&lt;br /&gt;There may be a useful side effect here as well.  When people see a site enhanced by the latest web browsers, we may get more users switching from older and less standards compliant browsers to the more modern and better newer browsers.&lt;br /&gt;&lt;br /&gt;We may have to use vendor specific prefixes to get some effects to work, but I think that is a small price to pay to help push forwards the use of the good parts of CSS3.&lt;br /&gt;&lt;br /&gt;The best part of all this is that as new browsers are released and used, our websites will look better and a good level of support is on the horizon.  Safari 3 already has a good level of support, IE8 will have some and Firefox 3.1 will have a good level of support.  With Safari having decent support for CSS3, it means all modern Webkit browsers should as well - read Chrome and the iPhone browser in particular!&lt;br /&gt;&lt;br /&gt;So which properties might be able to be used in this way?  Here are a few select ones that I think could be useful:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;box-shadow&lt;/span&gt;&lt;br /&gt;With this effect, we can create drop shadows around boxes.  When this property is not understood, there is no detrimental effect and when it is recognised, a nice enhancement can be achieved.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;border-radius&lt;/span&gt;&lt;br /&gt;This effect allows us to create rounded corners using only CSS.  I think this is useful as its simpler than any other technique and support can be achieved for IE by using conditional comments to include other stylesheets.  Firefox 3 and Safari 3 already have support for this property - definitely one of the most useful to start implementing.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;text-shadow&lt;/span&gt;&lt;br /&gt;Similar to box-shadow, this effect will create a drop shadow effect around text.  Another nice enhancement.  Not strictly a new addition in CSS3, but support seems to be coming with CSS3 support.&lt;br /&gt;&lt;br /&gt;There are other interesting effects coming, but I think these are the most potentially useful when applied using the principles of progressive enhancement.  There are also a couple of useful new selectors coming, but its hard to see how one could use them with the principles of progressive enhancement.&lt;br /&gt;&lt;br /&gt;I am excited about some of the new features of CSS3 and its great to be able to start using some.  Indeed, the new JSquared website will feature some new CSS3 effects applied in this way.&lt;br /&gt;&lt;br /&gt;What we do need to be cautious of though is creating a complete maintenance headache.  Lets start using new features, but sparingly at first.  We dont want to make development even harder with yet another class of browser to support.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8421903615286376978-1176264153730656322?l=nortools.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nortools.blogspot.com/feeds/1176264153730656322/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8421903615286376978&amp;postID=1176264153730656322' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/1176264153730656322'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/1176264153730656322'/><link rel='alternate' type='text/html' href='http://nortools.blogspot.com/2009/01/using-css3.html' title='Using CSS3'/><author><name>James Norton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8421903615286376978.post-7633556035532113238</id><published>2009-01-07T12:34:00.002Z</published><updated>2009-01-07T12:40:13.798Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='JSquared'/><category scheme='http://www.blogger.com/atom/ns#' term='off-topic'/><title type='text'>Happy new year</title><content type='html'>I wish you all a (slightly) belated happy new year.&lt;br /&gt;&lt;br /&gt;2008 was a tough but amazing year.  Some of its highlights for me included getting married, having an amazing honeymoon and having 3 different jobs!&lt;br /&gt;&lt;br /&gt;Some of the less good parts included having 3 different jobs!  I am working harder than ever now at home and at work and have had much less time in the last 6 months to blog or work on &lt;a href="http://www.j-squared.info"&gt;JSquared&lt;/a&gt; than I would have liked.&lt;br /&gt;&lt;br /&gt;But things can change for 2009 and so I hope to only have 1 job this year, not get married again (as amazing as that was) and give a bit more time to blogging here.&lt;br /&gt;&lt;br /&gt;As you can see on the &lt;a href="http://blog.j-squared.info/"&gt;JSquared blog&lt;/a&gt;, work has resumed on the project after a period of quiet and I have a new team member on board to make the project even better and an even bigger success.&lt;br /&gt;&lt;br /&gt;This is hardly going to be a quiet year though as I hope to move house - here's hoping Mrs N and myself can find the right place!&lt;br /&gt;&lt;br /&gt;I hope you all have a happy, healthy and successful year and keep reading....&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8421903615286376978-7633556035532113238?l=nortools.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nortools.blogspot.com/feeds/7633556035532113238/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8421903615286376978&amp;postID=7633556035532113238' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/7633556035532113238'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/7633556035532113238'/><link rel='alternate' type='text/html' href='http://nortools.blogspot.com/2009/01/happy-new-year.html' title='Happy new year'/><author><name>James Norton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8421903615286376978.post-994825202542482307</id><published>2008-11-18T14:25:00.005Z</published><updated>2008-11-18T14:44:40.288Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='rant'/><category scheme='http://www.blogger.com/atom/ns#' term='off-topic'/><title type='text'>A rant</title><content type='html'>I have tried hard not to fill this blog with random off-topic rants.  I am about to break that rule.  If you do not wish to read my rant, please move on - normal service will be resumed shortly.&lt;br /&gt;&lt;br /&gt;There is some (tenuous) relevancy about this rant.  I will mention user interfaces!&lt;br /&gt;&lt;br /&gt;My rant is about iPod's.  No no, sorry, its about iPod users and iPod headphones.&lt;br /&gt;&lt;br /&gt;I use an iPod.  I use it because it was given to me and is 8Gb whereas my MP3 player of choice (a Creative Zen Stone Plus) is only 4Gb.  It is a 3rd gen nano and is truly wondrous to hold and behold.  I find the sound quality lacking in comparison to the two Creative players I have had, but it serves my needs adequately.&lt;br /&gt;&lt;br /&gt;I am not such a fan of using the iPod.  I often find myself getting frustrated at the imprecise and slow controls - I just want to move to a position within a track and change volume without waiting for the interface to allow me!&lt;br /&gt;&lt;br /&gt;Anyway, I was sitting on the train this morning - not listening to my iPod - and the woman sitting next to me was listening to hers with the rather poor, but iconic iPod headphones. &lt;br /&gt;&lt;br /&gt;She felt she had to have the volume turned to maximum just to be able to hear her music through those rubbish and very leaky headphones!  This resulted in the whole carriage "enjoying" her music along with her.  And I got the brunt of it.&lt;br /&gt;&lt;br /&gt;In short - if you have an iPod, buy some decent headphones!&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:75%"&gt;&amp;lt;/rant&amp;gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8421903615286376978-994825202542482307?l=nortools.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nortools.blogspot.com/feeds/994825202542482307/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8421903615286376978&amp;postID=994825202542482307' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/994825202542482307'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/994825202542482307'/><link rel='alternate' type='text/html' href='http://nortools.blogspot.com/2008/11/rant.html' title='A rant'/><author><name>James Norton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8421903615286376978.post-271535779573696795</id><published>2008-11-03T17:16:00.003Z</published><updated>2008-11-03T17:21:55.208Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Web standards'/><category scheme='http://www.blogger.com/atom/ns#' term='Browsers'/><title type='text'>Browser wars</title><content type='html'>To finish up this little series of posts about browser standards, I wanted to refer to the browser wars and ask this simple question:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:150%;" &gt;Do we need another browser war?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Well?  What do you think?&lt;br /&gt;&lt;br /&gt;I think we cannot have another browser war in quite the same way.  When it was Netscape vs Internet Explorer, every user spoke (or perhaps didn't speak) and chose (or perhaps was simply given) Internet Explorer.  What then happened is that all the proprietary features of IE could be safely used whilst knowing there was a very high support rate.&lt;br /&gt;&lt;br /&gt;Since IE6 came out and the browser war ended, there was a little stagnation but really what happened was that people got a bit bored and wanted more.  So Firefox came along as a viable competitor.  That was the time to have a browser war.  The moment has passed.  &lt;br /&gt;&lt;br /&gt;Right now there is too much competition (or maybe none - its hard to tell) between the browser vendors.  The market is too segmented.  We now need the vendors to follow a standard spec.  And so we get into the sordid world of the W3C and standards.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8421903615286376978-271535779573696795?l=nortools.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nortools.blogspot.com/feeds/271535779573696795/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8421903615286376978&amp;postID=271535779573696795' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/271535779573696795'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/271535779573696795'/><link rel='alternate' type='text/html' href='http://nortools.blogspot.com/2008/11/browser-wars.html' title='Browser wars'/><author><name>James Norton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8421903615286376978.post-9194808781536347988</id><published>2008-11-03T16:56:00.003Z</published><updated>2008-11-03T17:16:06.593Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript 2'/><category scheme='http://www.blogger.com/atom/ns#' term='CSS 3'/><category scheme='http://www.blogger.com/atom/ns#' term='Browser support'/><category scheme='http://www.blogger.com/atom/ns#' term='Web standards'/><category scheme='http://www.blogger.com/atom/ns#' term='Browsers'/><category scheme='http://www.blogger.com/atom/ns#' term='HTML 5'/><title type='text'>Standards?</title><content type='html'>Yesterday, I posted about &lt;a href="http://nortools.blogspot.com/2008/10/standard-nonsense.html"&gt;some of my thoughts on web standards&lt;/a&gt;.  It raised some questions for me. It was a post I was reluctant to make but only because I could not reasonably say in one post how I feel and what I think about the current state of affairs.  I don't want this blog to descend into a series of rants about the W3C and standards etc etc.&lt;br /&gt;&lt;br /&gt;I will attempt now to clarify my thoughts on where we should go from here.&lt;br /&gt;&lt;br /&gt;Firstly, I think we do need to make progress.  We need to move things forwards.  We cannot stagnate.  We must find ways to innovate.  However, I don't think we have even scratched the surface of what is commercially possible and viable given today's technology.  The browser has proven itself to be a remarkable platform capable of producing almost any sort of UI.&lt;br /&gt;&lt;br /&gt;So here are some thoughts for each proposed standard:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;HTML 5&lt;br /&gt;I am unconvinced by large parts of the spec and I think it is far too large a specification.  I want to see greater interoperability between the various browsers and as such I believe simplification would be better.  I also strongly believe that the next spec should enforce an XML type syntax.  Its easier to maintain and easier to find errors.  I would encourage the browser vendors to simplify their parsing engines, not force them into more complicated solutions.&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;CSS 3&lt;br /&gt;The power of CSS is in its expressive simplicity.  This will not be lost within CSS 3, but do we really need much more on top of CSS 2.1?  Do we need to have 4 rendering engines in wide use which are trying to implement a load of new CSS properties that will not be widely used?  Are we not better off getting the current specs properly implemented with perhaps a few additions (multiple background images comes to mind) which can be progressively applied using the principles of progressive enhancement?&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;JavaScript 2&lt;br /&gt;I do not think JavaScript should gain classes and I do not think the language should be greatly extended.  Interfaces may be a useful addition, but generally I just think a little tidying is needed.  Its in the DOM that work is required.  Lets get the DOM objects of the various browsers to be more closely aligned with each other.&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;What I am generally advocating is a simplification of the specs to make them manageable for browser vendors.  Lets give the browser vendors an easier task to get themselves up to scratch and then lets ask them to add new features.  As always these new features should be able to be applied using the principles of progressive enhancement.&lt;br /&gt;&lt;br /&gt;The savior for us all could be JavaScript libraries.  They transcend the browser differences hiding them conveniently.  Of course that creates a level of ignorance about those issues amongst some, but they are undeniably popular and successful.&lt;br /&gt;&lt;br /&gt;But the world of JavaScript libraries is amazingly similar to the early world of the browser.  They all do basically the same things but in quite different ways.  Some libraries do some things well, others do other things well.  Funnily enough, libraries need to converge on something of a unified API.  Just like the browsers.&lt;br /&gt;&lt;br /&gt;So for the foreseeable future, the web developer will continue to bridge the gap with ingenuity, cunning, blood, sweat and tears.  Its OK for me, but will it still be OK in 10 years time?  Will we still be in the same situation in 10 years time?  Sadly, I think yes.  Does this dull my passion for my job?  Absolutely not!  I enjoy dealing with these vagaries and having to think on my feet every day!&lt;br /&gt;&lt;br /&gt;Surely though, we can sort this out, one way or another...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8421903615286376978-9194808781536347988?l=nortools.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nortools.blogspot.com/feeds/9194808781536347988/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8421903615286376978&amp;postID=9194808781536347988' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/9194808781536347988'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/9194808781536347988'/><link rel='alternate' type='text/html' href='http://nortools.blogspot.com/2008/11/standards.html' title='Standards?'/><author><name>James Norton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8421903615286376978.post-4945471673699206168</id><published>2008-10-31T15:47:00.008Z</published><updated>2008-10-31T17:04:23.448Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript 2'/><category scheme='http://www.blogger.com/atom/ns#' term='CSS 3'/><category scheme='http://www.blogger.com/atom/ns#' term='Browser support'/><category scheme='http://www.blogger.com/atom/ns#' term='Web standards'/><category scheme='http://www.blogger.com/atom/ns#' term='Browsers'/><category scheme='http://www.blogger.com/atom/ns#' term='HTML 5'/><title type='text'>Standard nonsense</title><content type='html'>My thoughts on web standards change on an almost weekly basis.  I now consider myself a sceptical evangelist!  I believe in web standards as an end but I do not agree with the means by which we seem to be getting there.  I think we should be using web standards, but I live and work in the real world where web standards remain nothing more than a laudable goal and an occasional convenient excuse.&lt;br /&gt;&lt;br /&gt;Currently, we have HTML 5 and CSS 3  and JavaScript 2 as the shining examples of where we are heading with web standards.  I am aware that JavaScript 2 is no more (the end of a great folly in my opinion), however, these three serve to demonstrate my point.&lt;br /&gt;&lt;br /&gt;The vast majority of users on the web, and surely its the users who are most important - not us developers, are using Internet Explorer as their primary web browser.  IE is a fine product for browsing the web today and I suspect it fulfills the needs of those users in the vast majority of cases.  &lt;br /&gt;&lt;br /&gt;A good proportion of users are using Firefox with many using Firefox 3.  This too is a fine browser.  As is Safari which dominates the remaining small proportion of users.&lt;br /&gt;&lt;br /&gt;At this point, others may launch into a diatribe about how users should switch browsers.  Some may wish to analyse the statistics on a deeper level.  But I wish to just re-iterate that for users, their current browser works fine!  Why are we - the developers - getting so upset about users not changing their browser?&lt;br /&gt;&lt;br /&gt;HTML 5, CSS 3 and JavaScript 2 are (or were) all meant to be innovations and additions to the interface developers toolkit, allowing us to do exciting new and innovative things.  Creating new types of web pages, allowing the user to interact in new and exciting ways.  Hmm.  Writing that makes me think of AJAX.  AJAX was meant to be an innovation and an addition to the interface developers toolkit allowing us to do exciting new and innovative things.  AJAX was meant to allow us to create new types of web pages, allowing the user to interact in new and exciting ways.&lt;br /&gt;&lt;br /&gt;Why did it work with AJAX?  Its because support was already in the users browser.  When AJAX started to become popular, there were some older browsers in use almost as much as Firefox 2 is in use today.  Well, those older browsers disappeared as users could not access the websites that used advanced AJAX techniques.  The other very helpful factor for AJAX was that computers became very cheap and very powerful and so users were upgrading more easily and more frequently.  Most users only change browser when they change computer.&lt;br /&gt;&lt;br /&gt;I believe there are the following 3 main reasons that HTML 5 and CSS 3 are not in common use today and will not be for at least 5 years from now:&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;The W3C&lt;br /&gt;A large slow moving organisation that seemingly cannot decide in which direction to lumber.  There has been some progress over the last year, but they have absolutely set the pace.  The gap between HTML 4 and HTML 5 being proper standards will be mirrored by the gap between users using browsers which implement those standards.&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;The browser vendors&lt;br /&gt;More slow moving organisations.  The era of co-operation never began and never will be.  There seems to be more effort being made to improve the performance of existing browser features rather than in implementing anything new.  This in itself is a positive, but it does not really move the game forwards.  This is the vendors playing catch-up so the websites we already build can run in a more reasonable fashion.&lt;br /&gt;&lt;br /&gt;There appears to be so little real competition in this market that vendor specific features are becoming acceptable again within the web development community.  As developers we just want something shiny and new to play with!&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;The Users&lt;br /&gt;The only group that should really matter.  Users have not been given any real incentive to change browsers or to support those vendors attempting to implement and push forwards new standards.  Users will only shift their position on this in response to catastrophic security issues or a family member who knows better and has a convincing voice.&lt;br /&gt;&lt;br /&gt;Users still use older browsers such as IE 6 and Firefox 2 because there is nothing that the newer browsers offer which is compelling enough to make the change.  Users are not technically savvy and nor should they have to be.  Users only demand reliability, usable performance and security - even IE 6 can provide that.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;Ultimately, there is no business case for building a website implementing new standards.  Indeed, the opposite is true - it is better for businesses to ensure their websites work on the widest cross-section of browsers out there which means implementing old standards.&lt;br /&gt;&lt;br /&gt;So is this all a cause for depression?  Absolutely not.  Do we need new standards?  Not really!  Wow, that was a controversial statement.  I would like new and more appropriate standards, I would like those standards to be adhered to so I don't have to deal with cross browser issues.  But, I am still doing really exciting and innovative work, I still find new bugs and issues with the browsers and I am yet to see a design or specification for a website which I could not build with today's existing technologies.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8421903615286376978-4945471673699206168?l=nortools.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nortools.blogspot.com/feeds/4945471673699206168/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8421903615286376978&amp;postID=4945471673699206168' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/4945471673699206168'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/4945471673699206168'/><link rel='alternate' type='text/html' href='http://nortools.blogspot.com/2008/10/standard-nonsense.html' title='Standard nonsense'/><author><name>James Norton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8421903615286376978.post-4172906205293490874</id><published>2008-10-30T16:15:00.004Z</published><updated>2008-10-30T16:30:44.465Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Usability'/><category scheme='http://www.blogger.com/atom/ns#' term='Mobile'/><category scheme='http://www.blogger.com/atom/ns#' term='Interface development'/><category scheme='http://www.blogger.com/atom/ns#' term='Accessibility'/><category scheme='http://www.blogger.com/atom/ns#' term='Browsers'/><category scheme='http://www.blogger.com/atom/ns#' term='Opera'/><title type='text'>The Quiet</title><content type='html'>Its been pretty quiet on this blog for the last 6 weeks or so.  I have been very busy working on an interesting, fairly complex and fairly large JavaScript application during the day and then recovering from it at night!  I also had the pleasure of a lovely week away in this period of quiet.&lt;br /&gt;&lt;br /&gt;I have also recently got my hands on a rather sexy new phone - an HTC Touch Diamond - and have spent a lot of time playing with that.  Its a Windows Mobile PocketPC and its been an interesting experience, particularly Opera 9.5 Mobile which is the default browser.&lt;br /&gt;&lt;br /&gt;Browsing on a handheld device has been a new experience for me.  My phone comes with Pocket IE installed as well, but that is rather archaic.  I have done all I can to avoid using it.&lt;br /&gt;&lt;br /&gt;Opera Mobile however is a fantastic browser.  Its fairly fast, pretty standards compliant and renders most pages rather well.  It has also given me a useful insight into a different type of user agent for browsing the web.  Its quite a different experience and its easy to see which sites are well designed and which are not.&lt;br /&gt;&lt;br /&gt;I have taken away a couple of important lessons from my experience.  Firstly, clear interface design is very important on this type of device.  The browser can zoom into pages but when a page loads, it is zoomed out and most text cannot be read clearly at all.  However, a site with good design is very usable as I can zoom in on just the right area.  Clearly defined navigation really helps with browsing on a mobile device.&lt;br /&gt;&lt;br /&gt;The second lesson I have learnt is that the easiest sites to use employ a liquid or semi-liquid layout.  My phone has a resolution of 480x640 and if a site can flow its content to fit into either of those widths, that helps greatly.  If I were designing a website today, I would definitely ensure it works in a browser width of 640 pixels!&lt;br /&gt;&lt;br /&gt;The final lesson I have taken with me thus far is that the size of elements on screen really matters.  I use my finger to navigate a website and having links tightly packed together with a small font size makes life very difficult.  Having small form fields or form fields with a small font size and another link right next to or just underneath the form field can make it difficult to select the element I want to interact with.  Finally, having heavily styled buttons, especially image buttons makes submitting a form harder than it needs to be, particularly if pressing enter on the keyboard does not work.&lt;br /&gt;&lt;br /&gt;For me, the most noteworthy new aspect of interface development that I will carry with me is the importance of keyboard interaction with a form - never ever stop a form being submitted with the enter key!&lt;br /&gt;&lt;br /&gt;There is much more to say about this phone and browsing the web using Opera, but at least for now, the quiet is no more!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8421903615286376978-4172906205293490874?l=nortools.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nortools.blogspot.com/feeds/4172906205293490874/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8421903615286376978&amp;postID=4172906205293490874' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/4172906205293490874'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/4172906205293490874'/><link rel='alternate' type='text/html' href='http://nortools.blogspot.com/2008/10/quiet.html' title='The Quiet'/><author><name>James Norton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8421903615286376978.post-4687136186057871586</id><published>2008-09-17T16:10:00.000+01:00</published><updated>2008-09-17T16:18:04.260+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='JSquared'/><title type='text'>Another JavaScript pattern - private members shared between object instances</title><content type='html'>In this post, I will introduce another pattern to add to &lt;a href="http://nortools.blogspot.com/2008/06/my-javascript-patterns.html"&gt;my previous post about my JavaScript patterns&lt;/a&gt;.  In fact, this is an extension to those patterns and combines both patterns together!  This is a singleton pattern that creates a constructor!&lt;br /&gt;&lt;br /&gt;In this post I will also make use of some aspects of JSquared, so please refer to &lt;a href="http://www.j-squared.info/"&gt;the JSquared website&lt;/a&gt; for more information on those.&lt;br /&gt;&lt;br /&gt;So, private members shared between object instances.  What does that mean?  What it means is that I want to have some private variables and functions which are accessible to multiple instances of a constructor but without them being part of the constructor or the objects the constructor will create. A fairly well known way of achieving this is by making the prototype of my constructor an object built using something similar to my singleton pattern.  This would allow public and private members on the prototype of my object.  But that will not give me all I wish to achieve this time and it can be a clumsy syntax.&lt;br /&gt;&lt;br /&gt;The code I will use to help explain this concept is designed to be a simple panel object.  The object will manage a series of panels on a webpage which are linked.  Only one panel can be open at a time.  Typically one would construct this with a singleton object which finds all instances of the panels in the DOM and adds some handling to each DOM node accordingly.  I will do this in a different way.  This code example is of course merely a skeleton.&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: Consolas; font-size: 10pt; color: black; background: #e1e1e1; padding:10px;"&gt;&lt;p style="margin: 0px; margin:0;"&gt;&lt;span style="color: blue;"&gt;var&lt;/span&gt; Panel = &lt;span style="color: blue;"&gt;new&lt;/span&gt; (&lt;span style="color: blue;"&gt;function&lt;/span&gt;() {&lt;/p&gt;&lt;p style="margin: 0px; margin:0;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px; margin:0;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;//add a DOM load event &lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px; margin:0;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; addLoadEvent( &lt;span style="color: blue;"&gt;function&lt;/span&gt;() {&lt;/p&gt;&lt;p style="margin: 0px; margin:0;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;//get all DIV elements with a class of "panel"&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px; margin:0;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; document.getElementsByClassName( {cssClass: &lt;span style="color: #a31515;"&gt;"panel"&lt;/span&gt;, tags: &lt;span style="color: #a31515;"&gt;"div"&lt;/span&gt;, callback: &lt;span style="color: blue;"&gt;function&lt;/span&gt;() {&lt;/p&gt;&lt;p style="margin: 0px; margin:0;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;//create a new instance of the Panel constructor for each panel&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px; margin:0;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;new&lt;/span&gt; Panel(&lt;span style="color: blue;"&gt;this&lt;/span&gt;);&lt;/p&gt;&lt;p style="margin: 0px; margin:0;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; } } );&lt;/p&gt;&lt;p style="margin: 0px; margin:0;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } );&lt;/p&gt;&lt;p style="margin: 0px; margin:0;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px; margin:0;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; panels = [];&lt;/p&gt;&lt;p style="margin: 0px; margin:0;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px; margin:0;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;function&lt;/span&gt; closeAll() {&lt;/p&gt;&lt;p style="margin: 0px; margin:0;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;for&lt;/span&gt; (&lt;span style="color: blue;"&gt;var&lt;/span&gt; i = panels.length-1; i&amp;gt;=0; i--) {&lt;/p&gt;&lt;p style="margin: 0px; margin:0;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; panels[i].close();&lt;/p&gt;&lt;p style="margin: 0px; margin:0;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p style="margin: 0px; margin:0;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p style="margin: 0px; margin:0;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px; margin:0;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;//return the Panel constructor&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px; margin:0;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;return&lt;/span&gt; &lt;span style="color: blue;"&gt;function&lt;/span&gt;(panelNode) {&lt;/p&gt;&lt;p style="margin: 0px; margin:0;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;this&lt;/span&gt;.open = &lt;span style="color: blue;"&gt;function&lt;/span&gt;() {&lt;/p&gt;&lt;p style="margin: 0px; margin:0;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; closeAll();&lt;/p&gt;&lt;p style="margin: 0px; margin:0;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;//perform the open logic&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px; margin:0;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p style="margin: 0px; margin:0;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;this&lt;/span&gt;.close = &lt;span style="color: blue;"&gt;function&lt;/span&gt;() {&lt;/p&gt;&lt;p style="margin: 0px; margin:0;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;//perform the close logic&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px; margin:0;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p style="margin: 0px; margin:0;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;//add this instance to the all instances array inside the closure&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px; margin:0;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; panels.push(&lt;span style="color: blue;"&gt;this&lt;/span&gt;);&lt;/p&gt;&lt;p style="margin: 0px; margin:0;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p style="margin: 0px; margin:0;"&gt;});&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Lets step through each part of this example and see what it does:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: Consolas; font-size: 10pt; color: black; background: #e1e1e1; padding:10px;"&gt;&lt;p style="margin: 0px; margin:0;"&gt;&lt;span style="color: blue;"&gt;var&lt;/span&gt; Panel = &lt;span style="color: blue;"&gt;new&lt;/span&gt; (&lt;span style="color: blue;"&gt;function&lt;/span&gt;() {&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;Create a new variable called &lt;span style="font-style:italic;"&gt;Panel&lt;/span&gt; using the singleton pattern.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: Consolas; font-size: 10pt; color: black; background: #e1e1e1; padding:10px;"&gt;&lt;p style="margin: 0px; margin:0;"&gt;&lt;span style="color: green;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //add a DOM load event &lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px; margin:0;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; addLoadEvent( &lt;span style="color: blue;"&gt;function&lt;/span&gt;() {&lt;/p&gt;&lt;p style="margin: 0px; margin:0;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;//get all DIV elements with a class of "panel"&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px; margin:0;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; document.getElementsByClassName( {cssClass: &lt;span style="color: #a31515;"&gt;"panel"&lt;/span&gt;, tags: &lt;span style="color: #a31515;"&gt;"div"&lt;/span&gt;, callback: &lt;span style="color: blue;"&gt;function&lt;/span&gt;() {&lt;/p&gt;&lt;p style="margin: 0px; margin:0;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;//create a new instance of the Panel constructor for each panel&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px; margin:0;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;new&lt;/span&gt; Panel(&lt;span style="color: blue;"&gt;this&lt;/span&gt;);&lt;/p&gt;&lt;p style="margin: 0px; margin:0;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; } } );&lt;/p&gt;&lt;p style="margin: 0px; margin:0;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } );&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;Using JSquared methods add an event handler for when the documents loads.  The handler will use another JSquared method to find all elements in the document which are &lt;span style="font-style:italic;"&gt;DIV&lt;/span&gt;s with a class of &lt;span style="font-style:italic;"&gt;panel&lt;/span&gt; and for each one run the supplied function which will create a new instance of &lt;span style="font-style:italic;"&gt;Panel&lt;/span&gt; passing in the &lt;span style="font-style:italic;"&gt;DIV&lt;/span&gt; node with the class &lt;span style="font-style:italic;"&gt;panel&lt;/span&gt; that was found. (see &lt;a href="http://www.j-squared.info/docs/"&gt;the JSquared docs&lt;/a&gt; for more info on how &lt;span style="font-style:italic;"&gt;getElementsByClassName&lt;/span&gt; is used)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: Consolas; font-size: 10pt; color: black; background: #e1e1e1; padding:10px;"&gt;&lt;p style="margin: 0px; margin:0;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; var&lt;/span&gt; panels = [];&lt;/p&gt;&lt;p style="margin: 0px; margin:0;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px; margin:0;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;function&lt;/span&gt; closeAll() {&lt;/p&gt;&lt;p style="margin: 0px; margin:0;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;for&lt;/span&gt; (&lt;span style="color: blue;"&gt;var&lt;/span&gt; i = panels.length-1; i&amp;gt;=0; i--) {&lt;/p&gt;&lt;p style="margin: 0px; margin:0;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; panels[i].close();&lt;/p&gt;&lt;p style="margin: 0px; margin:0;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p style="margin: 0px; margin:0;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;These are the private members which each instance of &lt;span style="font-style:italic;"&gt;Panel&lt;/span&gt; will have access to.  We have an array of panels which will get filled with each instance of &lt;span style="font-style:italic;"&gt;Panel&lt;/span&gt; that is created and we have a &lt;span style="font-style:italic;"&gt;closeAll&lt;/span&gt; method that loops through each instance of &lt;span style="font-style:italic;"&gt;Panel&lt;/span&gt; and calls its &lt;span style="font-style:italic;"&gt;close&lt;/span&gt; method.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: Consolas; font-size: 10pt; color: black; background: #e1e1e1; padding:10px;"&gt;&lt;p style="margin: 0px; margin:0;"&gt;&lt;span style="color: green;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //return the Panel constructor&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px; margin:0;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;return&lt;/span&gt; &lt;span style="color: blue;"&gt;function&lt;/span&gt;(panelNode) {&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;We are going to return a constructor (using the standard constructor pattern).  The variable &lt;span style="font-style:italic;"&gt;Panel&lt;/span&gt; that we created at the top of the code example will now take the value of this constructor.  In other words, &lt;span style="font-style:italic;"&gt;Panel&lt;/span&gt; becomes a constructor which we can create instances of using the &lt;span style="font-family: Consolas; font-size: 10pt; color: black;"&gt;&lt;span style="color: blue;"&gt;new&lt;/span&gt;&lt;/span&gt; keyword.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: Consolas; font-size: 10pt; color: black; background: #e1e1e1; padding:10px;"&gt;&lt;p style="margin: 0px; margin:0;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; this&lt;/span&gt;.open = &lt;span style="color: blue;"&gt;function&lt;/span&gt;() {&lt;/p&gt;&lt;p style="margin: 0px; margin:0;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; closeAll();&lt;/p&gt;&lt;p style="margin: 0px; margin:0;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;//perform the open logic&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px; margin:0;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p style="margin: 0px; margin:0;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;this&lt;/span&gt;.close = &lt;span style="color: blue;"&gt;function&lt;/span&gt;() {&lt;/p&gt;&lt;p style="margin: 0px; margin:0;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;//perform the close logic&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px; margin:0;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;Create &lt;span style="font-style:italic;"&gt;open&lt;/span&gt; and &lt;span style="font-style:italic;"&gt;close&lt;/span&gt; methods which will perform those actions.  In the open method, we first want to close all the panels ensuring only one can be open at any time.  To do that we call the private &lt;span style="font-style:italic;"&gt;closeAll&lt;/span&gt; method which is available through the closure around &lt;span style="font-style:italic;"&gt;Panel&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: Consolas; font-size: 10pt; color: black; background: #e1e1e1; padding:10px;"&gt;&lt;p style="margin: 0px; margin:0;"&gt;&lt;span style="color: green;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; //add this instance to the all instances array inside the closure&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px; margin:0;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; panels.push(&lt;span style="color: blue;"&gt;this&lt;/span&gt;);&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;Add this new instance (this line of code is still part of the &lt;span style="font-style:italic;"&gt;Panel&lt;/span&gt; constructor) to the private &lt;span style="font-style:italic;"&gt;panels&lt;/span&gt; array also available through the closure we have created.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;To recap, we use the singleton pattern to execute some logic before returning a constructor which is then available to us later on in the page execution.  We can use the closure this creates to make private members, declared inside the self executing function which is the singleton pattern.  These private members are available to each instance of the constructor but the members are not available anywhere else within any JavaScript - as is usual for a closure of this type.&lt;br /&gt;&lt;br /&gt;This can be a very powerful and useful pattern.  When building a large application, I believe it is good to keep public members of all objects to a minimum and I also prefer not to use the prototype of an object unless I am using inheritance.  This pattern achieves both of these aims in an elegant and encapsulated way.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8421903615286376978-4687136186057871586?l=nortools.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nortools.blogspot.com/feeds/4687136186057871586/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8421903615286376978&amp;postID=4687136186057871586' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/4687136186057871586'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/4687136186057871586'/><link rel='alternate' type='text/html' href='http://nortools.blogspot.com/2008/09/another-javascript-pattern-private.html' title='Another JavaScript pattern - private members shared between object instances'/><author><name>James Norton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8421903615286376978.post-4169872584205795594</id><published>2008-09-02T21:23:00.002+01:00</published><updated>2008-09-02T21:33:36.966+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Browsers'/><category scheme='http://www.blogger.com/atom/ns#' term='Google Chrome'/><title type='text'>Google Chrome</title><content type='html'>So, its finally happened.  Google's next step towards world domination is here, and its a web browser!  Its also pretty clever.  Indeed, I am writing this post in the new browser.&lt;br /&gt;&lt;br /&gt;Its called &lt;a href="http://www.google.com/chrome"&gt;Google Chrome&lt;/a&gt;.  The Google Chrome chrome is extremely minimal and I like it.  The tabs have certainly taken center stage and got a nice feel to it.  It is extremely fast to use and the JavaScript engine appears to be fast and well, I am impressed!&lt;br /&gt;&lt;br /&gt;Its well worth a download and a play, and dont forget the developer tools - yes, they are included in the browser.&lt;br /&gt;&lt;br /&gt;I wont go into any technical details as Google have done a good (if somewhat unusual) job of explaining things.  Check out the website for more information.&lt;br /&gt;&lt;br /&gt;My favourite feature so far is the way the browser remembers searches you perform on other sites and makes it so easy for new searches to be performed.&lt;br /&gt;&lt;br /&gt;If this is how Google are approaching their application development - and lets face it, no-one expected anything different - then I have high hopes for Android.  On that subject, I have recently become the proud owner of an HTC Touch Diamond which is a Windows Mobile phone and I am keeping my fingers crossed that Chrome Mobile is coming soon!&lt;br /&gt;&lt;br /&gt;As an aside, being a Webkit based browser, I was hoping that JSquared would "just work".  However, I will be doing some testing and you can expect another report soon, especially given the new JavaScript engine.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8421903615286376978-4169872584205795594?l=nortools.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nortools.blogspot.com/feeds/4169872584205795594/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8421903615286376978&amp;postID=4169872584205795594' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/4169872584205795594'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/4169872584205795594'/><link rel='alternate' type='text/html' href='http://nortools.blogspot.com/2008/09/google-chrome.html' title='Google Chrome'/><author><name>James Norton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8421903615286376978.post-2138337252979034037</id><published>2008-08-21T17:29:00.007+01:00</published><updated>2008-08-21T17:55:39.222+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript 2'/><category scheme='http://www.blogger.com/atom/ns#' term='ECMAScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Browser support'/><category scheme='http://www.blogger.com/atom/ns#' term='Interface development'/><category scheme='http://www.blogger.com/atom/ns#' term='Web standards'/><category scheme='http://www.blogger.com/atom/ns#' term='CSS'/><category scheme='http://www.blogger.com/atom/ns#' term='Browsers'/><title type='text'>The future of JavaScript</title><content type='html'>For those who have not heard, ECMAScript 4 is no more.  That also means that JavaScript 2 is currently at best paused.  Some will mourn this as a great loss.  I am not one of those.&lt;br /&gt;&lt;br /&gt;JavaScript 2 had some very interesting ideas in it, but I am far from convinced that it was the future.  I firmly believe that JavaScript 1.x has a long long way to run yet.&lt;br /&gt;&lt;br /&gt;It is not often that I will link to an article on Slashdot, but &lt;a href="http://developers.slashdot.org/article.pl?sid=08/08/21/1431225&amp;from=rss"&gt;this one&lt;/a&gt; piqued my interest.&lt;br /&gt;&lt;br /&gt;The future of JavaScript is very much tied up in the present and future of browsers.  Much of what I have to say here is also true about future versions of CSS.&lt;br /&gt;&lt;br /&gt;The problems we as web professionals face today is not due to a shortcoming of JavaScript or CSS or HTML.  They are due to shortcomings of the browsers.  Until browsers support the standards, there may as well not be standards.  &lt;br /&gt;&lt;br /&gt;So we have options.  We can introduce new ideas and new technologies which will only be supported by a sub-set of users for a fairly long period and will then fall into a category of technologies we are reticent to use due to the need to support older browsers.&lt;br /&gt;&lt;br /&gt;Or, we can wait for the browsers to catch up with the standards so that we can exploit them to the full, with guaranteed compatibility.&lt;br /&gt;&lt;br /&gt;Well, I dont fancy waiting something like 4 or 5 or even 6 years for browsers to catch up with the standards, I want to do cool, new and interesting things now.  So, we are left with the former of the 2 options I present above.&lt;br /&gt;&lt;br /&gt;Of course, the thing which allows us to push forward and use the new technologies of CSS and JavaScript which are being introduced and still provide a good level of cross browser support is JavaScript!  Look at how the innovative use of JavaScript, largely by library authors, has driven the W3C and browser vendors to introduce new native features to the browsers.  This is only of benefit to us.&lt;br /&gt;&lt;br /&gt;I firmly believe that changing the core nature of JavaScript now would undermine a lot of the good work of the last few years and it would also be to deny the true power of JavaScript as it stands today.  Yes, there is a barrier to people wanting to learn JavaScript - it can be complex, it is difficult to master - but this also is a good thing.  Ultimately the standard of JavaScript development will improve and we don't need a new version of the language to make this happen.&lt;br /&gt;&lt;br /&gt;JavaScript is an amazingly flexible language and finding new ways of bending it to our will is going to define the next set of standards, the next set of tools that we want to see, and it is the next set of standards that are far more likely to be adhered to than the current generation.&lt;br /&gt;&lt;br /&gt;We must not stifle innovation, we must encourage it.  Keeping a massive level of embedded knowledge whilst JavaScript is still at its infancy of true professionalism is the right way forward.  Maintaining the core of the language as it stands moving forward must be a good thing.  Yes, lets play with other languages in the browser, lets even use and support them, but where JavaScript is concerned, my message is clear - don't go changing!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8421903615286376978-2138337252979034037?l=nortools.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nortools.blogspot.com/feeds/2138337252979034037/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8421903615286376978&amp;postID=2138337252979034037' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/2138337252979034037'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/2138337252979034037'/><link rel='alternate' type='text/html' href='http://nortools.blogspot.com/2008/08/future-of-javascript.html' title='The future of JavaScript'/><author><name>James Norton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8421903615286376978.post-5332158039343087622</id><published>2008-07-30T21:00:00.000+01:00</published><updated>2008-07-30T22:40:24.549+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><title type='text'>Complex assignments</title><content type='html'>I find my coding style continues to evolve as time goes on.  This suggests to me that I am still a long way off getting it right!  However, it also gives me the chance to play with new ideas and introduce new concepts to my code.&lt;br /&gt;&lt;br /&gt;One new pattern that I seem to now be using more and more is one I call &lt;span style="font-style:italic;"&gt;Complex Assignments&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;To introduce this, it is useful to look at simple assignment code first.  An assignment is simply setting one thing equal to another:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: Consolas; font-size: 10pt; color: black; background: #e1e1e1; padding:10px;"&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;var&lt;/span&gt; myVariable = 1;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;this&lt;/span&gt;.myMember = &lt;span style="color: #a31515;"&gt;"Some text"&lt;/span&gt;;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;this&lt;/span&gt;.myMethod = &lt;span style="color: blue;"&gt;function&lt;/span&gt;() {&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ....&lt;/p&gt;&lt;p style="margin: 0px;"&gt;}&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;These are all simple assignments.  Sometimes though this is not enough.  Sometimes you need to set the value of a variable based on some parameter, eg:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: Consolas; font-size: 10pt; color: black; background: #e1e1e1; padding:10px;"&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;function&lt;/span&gt;( myParam ) {&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; myVariable;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;if&lt;/span&gt; (myParam === 1) {&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; myVariable = &lt;span style="color: #a31515;"&gt;"Some text"&lt;/span&gt;;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;span style="color: blue;"&gt;else&lt;/span&gt; {&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; myVariable = &lt;span style="color: #a31515;"&gt;"Some other text"&lt;/span&gt;;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p style="margin: 0px;"&gt;}&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Now of course this is a trivial example, but you may find yourself needing a more complex set of rules.  In that case, the logic around this assignment can become complex.  To alleviate this problem we will often delegate the assignment logic into a function.  This is perfectly acceptable and actually desirable and in a JavaScript object we can make a private function to do the work:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: Consolas; font-size: 10pt; color: black; background: #e1e1e1; padding:10px;"&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;function&lt;/span&gt; myObject() {&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;this&lt;/span&gt;.someValue = getSomeValue();&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;function&lt;/span&gt; getSomeValue() {&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;//do some work&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ..... &lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;return&lt;/span&gt; someValue;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p style="margin: 0px;"&gt;}&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;However, if this function is only going to get called once, there is no need to make it a named function.  In fact I find it neater to make it an anonymous function.  Of course, if its an anonymous function that only gets run once, we can make it a self invoking function.  To rewrite the example above:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: Consolas; font-size: 10pt; color: black; background: #e1e1e1; padding:10px;"&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;function&lt;/span&gt; myObject() {&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;this&lt;/span&gt;.someValue = (&lt;span style="color: blue;"&gt;function&lt;/span&gt;() {&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;//do some work&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ..... &lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;return&lt;/span&gt; someValue;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; })();&lt;/p&gt;&lt;p style="margin: 0px;"&gt;}&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;In this instance, the code looks very similar (if somewhat neater).  But, with this anonymous self invoked function, we are actually creating another level of scope which will get destroyed once the function has been executed.  This can be very useful and can be very efficient.  I also think the code is simple to understand and even better encapsulated.&lt;br /&gt;&lt;br /&gt;This is particularly useful for the setting of constant like variables.  I find myself using this pattern more and more as I find more occasions where I want a function to be used to assign a value to a variable.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8421903615286376978-5332158039343087622?l=nortools.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nortools.blogspot.com/feeds/5332158039343087622/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8421903615286376978&amp;postID=5332158039343087622' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/5332158039343087622'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/5332158039343087622'/><link rel='alternate' type='text/html' href='http://nortools.blogspot.com/2008/07/complex-assignments.html' title='Complex assignments'/><author><name>James Norton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8421903615286376978.post-1755092659952915411</id><published>2008-07-17T14:08:00.004+01:00</published><updated>2008-07-17T14:28:17.018+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><title type='text'>Coupling, API surface area and change change change</title><content type='html'>Recently I started a new job focusing much more heavily on JavaScript than before and having been in this new role for a little while and having got the release of JSquared 1.1 out of the way, I have had some time to think about what I have learnt so far.&lt;br /&gt;&lt;br /&gt;Firstly it must be said that I am thoroughly enjoying working more heavily with JavaScript and I have already learnt some wonderful and interesting things about the way that JavaScript operates and how to make it go a bit faster.  No, a LOT faster!  I will be talking about some of these things in the future and applying that knowledge to JSquared!&lt;br /&gt;&lt;br /&gt;Also, I have recently read the excellent book from Douglas Crockford espousing about the good parts of JavaScript.  However, what I saw in my new role did not conform too closely if at all to the Crockford way of thinking (which I happen to largely share).&lt;br /&gt;&lt;br /&gt;First off, the code that exists here is of a very high quality and is well organised, but I have started to realise that there are a number of things I would look to do differently if we could re-write all the code from scratch.&lt;br /&gt;&lt;br /&gt;The code has become fairly tightly coupled over time with one object requiring and expecting another object to exist and the second object creating a back reference to the first. There are a number of circular references if one looks through the various objects closely enough.  &lt;br /&gt;&lt;br /&gt;References to objects are being passed around freely and there is little control being exercised over how values should be accessed and a distinct lack of singletons being used when I believe they should be.&lt;br /&gt;&lt;br /&gt;This leads to a very large API surface area.  By this I mean that there are a large number of methods that each object needs to expose and a large number of object references being passed around when a smaller API with singletons where appropriate would be simpler.&lt;br /&gt;&lt;br /&gt;The combination of the above two things leads to a problem.  If you want to rebuild all or part of an object, it becomes more difficult as the objects have very little private code.  If an object exposes just a few methods and properties as its API, and retains the rest of its working as private internals, it becomes much easier and simpler to re-write or add to it.&lt;br /&gt;&lt;br /&gt;This is a JavaScript application which undergoes constant change by multiple people.  Whilst this is good, it does mean that there are more and more objects with wider and wider surface areas.  I personally believe that this will lead to the need for a complete re-write of large parts of the application sooner.&lt;br /&gt;&lt;br /&gt;This brings me on to my final point, a positive and a negative point.  The application is harder to learn and takes longer to become confident with because of this large API surface area.  I enjoy that though as I want the challenge!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8421903615286376978-1755092659952915411?l=nortools.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nortools.blogspot.com/feeds/1755092659952915411/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8421903615286376978&amp;postID=1755092659952915411' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/1755092659952915411'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/1755092659952915411'/><link rel='alternate' type='text/html' href='http://nortools.blogspot.com/2008/07/coupling-api-surface-area-and-change.html' title='Coupling, API surface area and change change change'/><author><name>James Norton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8421903615286376978.post-7226930721971586288</id><published>2008-07-12T14:31:00.002+01:00</published><updated>2008-07-12T14:38:33.185+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JSquared'/><title type='text'>JSquared 1.1</title><content type='html'>It is with pleasure that earlier today I was able to announce the launch of JSquared 1.1.  See &lt;a href="http://blog.j-squared.info/"&gt;the blog&lt;/a&gt; and &lt;a href="http://www.j-squared.info/"&gt;the website&lt;/a&gt; for more details.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8421903615286376978-7226930721971586288?l=nortools.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nortools.blogspot.com/feeds/7226930721971586288/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8421903615286376978&amp;postID=7226930721971586288' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/7226930721971586288'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/7226930721971586288'/><link rel='alternate' type='text/html' href='http://nortools.blogspot.com/2008/07/jsquared-11.html' title='JSquared 1.1'/><author><name>James Norton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8421903615286376978.post-8760582440728416563</id><published>2008-06-30T11:02:00.000+01:00</published><updated>2008-06-30T23:01:41.989+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Browsers'/><category scheme='http://www.blogger.com/atom/ns#' term='Firefox'/><title type='text'>Not lovely...</title><content type='html'>Well, its not often that I have had a bad word to say about Mozilla Firefox.  However, for the second time in a week, I now do.&lt;br /&gt;&lt;br /&gt;I have been aware of issues with the Mozilla implementation of &lt;span style="font-style:italic;"&gt;eval&lt;/span&gt; for some time, but the latest exposure was news to me and seemingly many others.&lt;br /&gt;&lt;br /&gt;Full details can be found &lt;a href="http://peter.michaux.ca/article/8069"&gt;here&lt;/a&gt;.  There is no reliable way round that I can find as yet so I will continue along the assumption that in the JavaScript world, nothing is safe.&lt;br /&gt;&lt;br /&gt;I will still use a module pattern (as I have discussed before in a &lt;a href="http://nortools.blogspot.com/2008/06/my-javascript-patterns.html"&gt;previous post&lt;/a&gt;) and I will still call "private" members private.  I will also continue to discourage the use of evil eval.&lt;br /&gt;&lt;br /&gt;Douglas Crockford has a few things to say about Firefox in general and had &lt;a href="http://blog.360.yahoo.com/blog-TBPekxc1dLNy5DOloPfzVvFIVOWMB0li?p=875"&gt;his own comments&lt;/a&gt; about this latest issue.&lt;br /&gt;&lt;br /&gt;I am deeply disappointed frankly.  Firefox 3 ruined my week last week (well, truthfully, Firebug was as much to blame) and now this.  I suppose its nice to see that other browser vendors make mistakes!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8421903615286376978-8760582440728416563?l=nortools.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nortools.blogspot.com/feeds/8760582440728416563/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8421903615286376978&amp;postID=8760582440728416563' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/8760582440728416563'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/8760582440728416563'/><link rel='alternate' type='text/html' href='http://nortools.blogspot.com/2008/06/not-lovely.html' title='Not lovely...'/><author><name>James Norton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8421903615286376978.post-598855420115507472</id><published>2008-06-29T01:22:00.001+01:00</published><updated>2008-06-29T22:14:47.368+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Tools'/><title type='text'>Lovely...</title><content type='html'>&lt;a href="http://elfz.laacz.lv/beautify/"&gt;This&lt;/a&gt; is a lovely little tool.&lt;br /&gt;&lt;br /&gt;There is nothing else one can really say about it!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8421903615286376978-598855420115507472?l=nortools.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nortools.blogspot.com/feeds/598855420115507472/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8421903615286376978&amp;postID=598855420115507472' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/598855420115507472'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/598855420115507472'/><link rel='alternate' type='text/html' href='http://nortools.blogspot.com/2008/06/lovely.html' title='Lovely...'/><author><name>James Norton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8421903615286376978.post-2458501785721619657</id><published>2008-06-24T08:00:00.000+01:00</published><updated>2008-06-24T09:46:33.936+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Interface development'/><category scheme='http://www.blogger.com/atom/ns#' term='Browsers'/><category scheme='http://www.blogger.com/atom/ns#' term='Firebug'/><title type='text'>Firefox  3</title><content type='html'>Well, it has been a good few days now that I have been running the release version of Firefox 3 and I thought I would share some of my experiences - both positive and negative.&lt;br /&gt;&lt;br /&gt;First off, I like the interface updates, the "awesome bar" and the speed improvements.    I have been very impressed with its stability as well.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;How are you finding Firefox 3 and Firebug?  Have you found a combination that works for you?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8421903615286376978-2458501785721619657?l=nortools.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nortools.blogspot.com/feeds/2458501785721619657/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8421903615286376978&amp;postID=2458501785721619657' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/2458501785721619657'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/2458501785721619657'/><link rel='alternate' type='text/html' href='http://nortools.blogspot.com/2008/06/firefox-3.html' title='Firefox  3'/><author><name>James Norton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8421903615286376978.post-2301898385599973472</id><published>2008-06-09T22:57:00.002+01:00</published><updated>2008-06-10T09:48:27.143+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Interface development'/><title type='text'>My JavaScript patterns</title><content type='html'>Since posting about &lt;a href="http://nortools.blogspot.com/2008/05/my-javascript-rules.html"&gt;my JavaScript "rules"&lt;/a&gt;, I have had a number of requests to expand on the patterns I use for developing my JavaScript objects.&lt;br /&gt;&lt;br /&gt;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 &lt;span style="font-style:italic;"&gt;new&lt;/span&gt; keyword will create an object based on its definition.  These objects are known as instances.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Constructor Pattern&lt;/span&gt;&lt;br /&gt;A constructor pattern is something which JavaScript has native support for.  Douglas Crockford has previously &lt;a href="http://javascript.crockford.com/private.html"&gt;talked about this pattern at length&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: Consolas; font-size: 10pt; color: black; background: #e1e1e1; padding:10px;"&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;function&lt;/span&gt; EventHandler() {&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;//constructor&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;//private members&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; registeredEvents = [];&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;//public methods&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;this&lt;/span&gt;.registerHandler = &lt;span style="color: blue;"&gt;function&lt;/span&gt;(func) {&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;if&lt;/span&gt; (&lt;span style="color: blue;"&gt;typeof&lt;/span&gt; func === &lt;span style="color: #a31515;"&gt;"function"&lt;/span&gt;) {&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; registeredEvents.push(func);&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;this&lt;/span&gt;.fire = &lt;span style="color: blue;"&gt;function&lt;/span&gt;() {&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;for&lt;/span&gt; (&lt;span style="color: blue;"&gt;var&lt;/span&gt; i = registeredEvents.length-1; i &amp;gt;= 0; i--) {&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; registeredEvents[i]();&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p style="margin: 0px;"&gt;}&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: Consolas; font-size: 10pt; color: black; background: #e1e1e1; padding:10px;"&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;var&lt;/span&gt; myEventHandler = &lt;span style="color: blue;"&gt;new&lt;/span&gt; eventHandler();&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Singleton Pattern&lt;/span&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;I also wanted the pattern to look similar to the constructor pattern above.  This should make it easier to code and maintain.&lt;br /&gt;&lt;br /&gt;For this example, I am using a simplified version of an object in &lt;a href="http://www.j-squared.info"&gt;JSquared&lt;/a&gt;.  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 &lt;a href="http://blog.j-squared.info/"&gt;the JSquared blog&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: Consolas; font-size: 10pt; color: black; background: #e1e1e1; padding:10px;"&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;var&lt;/span&gt; cookies = &lt;span style="color: blue;"&gt;new&lt;/span&gt; (&lt;span style="color: blue;"&gt;function&lt;/span&gt;() {&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;//private members&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; cookies = {};&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;//constructor&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;//get the current set of cookies&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; currentCookies = document.cookie.split(&lt;span style="color: #a31515;"&gt;";"&lt;/span&gt;);&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; cookie;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;//loop through current cookies and add their values to the cookies collection&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;for&lt;/span&gt; (&lt;span style="color: blue;"&gt;var&lt;/span&gt; i = currentCookies.length - 1; i &amp;gt;= 0; i--) {&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; cookie = currentCookies[i].split(&lt;span style="color: #a31515;"&gt;"="&lt;/span&gt;);&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;if&lt;/span&gt; (cookie.length &amp;gt;= 2) {&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; cookies[cookie[0]] = cookie[1];&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;//public methods&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;this&lt;/span&gt;.&lt;span style="color: blue;"&gt;set&lt;/span&gt; = &lt;span style="color: blue;"&gt;function&lt;/span&gt;(name, value, expiration) {&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; document.cookie = name + &lt;span style="color: #a31515;"&gt;"="&lt;/span&gt; + value + &lt;span style="color: #a31515;"&gt;";expires="&lt;/span&gt; + expiration + &lt;span style="color: #a31515;"&gt;";path=/"&lt;/span&gt;;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; cookies[name] = value;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;this&lt;/span&gt;.&lt;span style="color: blue;"&gt;get&lt;/span&gt; = &lt;span style="color: blue;"&gt;function&lt;/span&gt;(name) {&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;return&lt;/span&gt; cookies[name];&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;this&lt;/span&gt;.&lt;span style="color: blue;"&gt;delete&lt;/span&gt; = &lt;span style="color: blue;"&gt;function&lt;/span&gt;(name) {&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;this&lt;/span&gt;.&lt;span style="color: blue;"&gt;set&lt;/span&gt;(name, &lt;span style="color: #a31515;"&gt;""&lt;/span&gt;, -1);&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;delete&lt;/span&gt; cookies[name];&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p style="margin: 0px;"&gt;});&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;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.  &lt;br /&gt;&lt;br /&gt;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 &lt;span style="font-style:italic;"&gt;cookies&lt;/span&gt; will contain the singleton.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;As I seem to often say, its as simple as that!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8421903615286376978-2301898385599973472?l=nortools.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nortools.blogspot.com/feeds/2301898385599973472/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8421903615286376978&amp;postID=2301898385599973472' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/2301898385599973472'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/2301898385599973472'/><link rel='alternate' type='text/html' href='http://nortools.blogspot.com/2008/06/my-javascript-patterns.html' title='My JavaScript patterns'/><author><name>James Norton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8421903615286376978.post-3840679146639924032</id><published>2008-05-27T21:05:00.000+01:00</published><updated>2008-05-27T21:06:38.048+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Interface development'/><title type='text'>My JavaScript "rules"</title><content type='html'>In my day to day life, I see a lot of JavaScript code.  I see a lot of code written by others and a lot of code which I have written in the past.  As I look back over my own code and my coding style over the last 2 years or so, it is easy to see how far I have come and how much better my code is now.&lt;br /&gt;&lt;br /&gt;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:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;1. Be unobtrusive&lt;/span&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;2. Name your spaces&lt;/span&gt;&lt;br /&gt;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:&lt;br /&gt;&lt;!--&lt;br /&gt;{\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Consolas;}}{\colortbl;??\red0\green0\blue255;\red225\green225\blue225;\red0\green0\blue0;}??\fs20 \cf1\cb2\highlight2 var\cf0  Nortools = \{\};\par ??Nortools.Login = \{\};\par ??Nortools.Forms = \{\};}&lt;br /&gt;--&gt;&lt;br /&gt;&lt;div style="font-family: Consolas; font-size: 10pt; color: black; background: #e1e1e1; padding:10px;"&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;var&lt;/span&gt; Nortools = {};&lt;/p&gt;&lt;p style="margin: 0px;"&gt;Nortools.Login = {};&lt;/p&gt;&lt;p style="margin: 0px;"&gt;Nortools.Forms = {};&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;3. Cry over spilt milk&lt;/span&gt;&lt;br /&gt;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:&lt;br /&gt;&lt;!--&lt;br /&gt;{\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Consolas;}}{\colortbl;??\red0\green0\blue255;\red225\green225\blue225;\red0\green0\blue0;\red163\green21\blue21;}??\fs20 \cf1\cb2\highlight2 var\cf0  myConstructor = \cf1 function\cf0 () \{\};\par ??myConstructor.prototype = \cf1 new\cf0  (\cf1 function\cf0 () \{\par ??\tab \cf1 var\cf0  myPrivateMember = \cf4 "some value"\cf0 ;\par ??\tab \cf1 this\cf0 .getPrivateMemeber = \cf1 function\cf0 () \{\par ??\tab \tab \cf1 return\cf0  myPrivateMember;\par ??\tab \}\par ??\});}&lt;br /&gt;--&gt;&lt;br /&gt;&lt;div style="font-family: Consolas; font-size: 10pt; color: black; background: #e1e1e1; padding:10px;"&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;var&lt;/span&gt; myConstructor = &lt;span style="color: blue;"&gt;function&lt;/span&gt;() {};&lt;/p&gt;&lt;p style="margin: 0px;"&gt;myConstructor.prototype = &lt;span style="color: blue;"&gt;new&lt;/span&gt; (&lt;span style="color: blue;"&gt;function&lt;/span&gt;() {&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; myPrivateMember = &lt;span style="color: #a31515;"&gt;"some value"&lt;/span&gt;;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;this&lt;/span&gt;.getPrivateMemeber = &lt;span style="color: blue;"&gt;function&lt;/span&gt;() {&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;return&lt;/span&gt; myPrivateMember;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p style="margin: 0px;"&gt;});&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;This code may look odd, but the prototype of &lt;span style="font-style:italic;"&gt;myConstructor&lt;/span&gt; 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!&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;4. Separate&lt;/span&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;5. I object&lt;/span&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;6. JSON&lt;/span&gt;&lt;br /&gt;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:&lt;br /&gt;&lt;!--&lt;br /&gt;{\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Consolas;}}{\colortbl;??\red0\green0\blue255;\red225\green225\blue225;\red0\green0\blue0;\red163\green21\blue21;}??\fs20 \cf1\cb2\highlight2 var\cf0  myConstructor = \cf1 function\cf0 (param1, param2, param3) \{\par ??\tab param1 = param1 || \cf4 "defaultValue"\cf0 ;\par ??\tab param2 = param2 || \cf4 "defaultValue"\cf0 ;\par ??\tab param3 = param3 || \cf4 "defaultValue"\cf0 ;\par ??\};\par ??\cf1 var\cf0  myInstance = \cf1 new\cf0  myConstructor( \cf4 "value"\cf0 , \cf1 null\cf0 , \cf4 "value"\cf0  );}&lt;br /&gt;--&gt;&lt;br /&gt;&lt;div style="font-family: Consolas; font-size: 10pt; color: black; background: #e1e1e1; padding:10px;"&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;var&lt;/span&gt; myConstructor = &lt;span style="color: blue;"&gt;function&lt;/span&gt;(param1, param2, param3) {&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; param1 = param1 || &lt;span style="color: #a31515;"&gt;"defaultValue"&lt;/span&gt;;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; param2 = param2 || &lt;span style="color: #a31515;"&gt;"defaultValue"&lt;/span&gt;;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; param3 = param3 || &lt;span style="color: #a31515;"&gt;"defaultValue"&lt;/span&gt;;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;};&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;var&lt;/span&gt; myInstance = &lt;span style="color: blue;"&gt;new&lt;/span&gt; myConstructor( &lt;span style="color: #a31515;"&gt;"value"&lt;/span&gt;, &lt;span style="color: blue;"&gt;null&lt;/span&gt;, &lt;span style="color: #a31515;"&gt;"value"&lt;/span&gt; );&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;My preferred method is:&lt;br /&gt;&lt;!--&lt;br /&gt;{\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Consolas;}}{\colortbl;??\red0\green0\blue255;\red225\green225\blue225;\red0\green0\blue0;\red163\green21\blue21;}??\fs20 \cf1\cb2\highlight2 var\cf0  myConstructor = \cf1 function\cf0 (options) \{\par ??\tab \cf1 var\cf0  param1 = options.param1 || \cf4 "defaultValue"\cf0 ;\par ??\tab \cf1 var\cf0  param2 = options.param2 || \cf4 "defaultValue"\cf0 ;\par ??\tab \cf1 var\cf0  param3 = options.param3 || \cf4 "defaultValue"\cf0 ;\par ??\};\par ??\cf1 var\cf0  myInstance = \cf1 new\cf0  myConstructor( \{\par ??\tab param2: \cf4 "value"\cf0 , \par ??\tab param3: \cf4 "value"\par ??\cf0 \} );}&lt;br /&gt;--&gt;&lt;br /&gt;&lt;div style="font-family: Consolas; font-size: 10pt; color: black; background: #e1e1e1; padding:10px;"&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;var&lt;/span&gt; myConstructor = &lt;span style="color: blue;"&gt;function&lt;/span&gt;(options) {&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; param1 = options.param1 || &lt;span style="color: #a31515;"&gt;"defaultValue"&lt;/span&gt;;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; param2 = options.param2 || &lt;span style="color: #a31515;"&gt;"defaultValue"&lt;/span&gt;;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; param3 = options.param3 || &lt;span style="color: #a31515;"&gt;"defaultValue"&lt;/span&gt;;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;};&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;var&lt;/span&gt; myInstance = &lt;span style="color: blue;"&gt;new&lt;/span&gt; myConstructor( {&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; param2: &lt;span style="color: #a31515;"&gt;"value"&lt;/span&gt;, &lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; param3: &lt;span style="color: #a31515;"&gt;"value"&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;} );&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;Much neater and I find it much easier to understand and read.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;7. Be a detective&lt;/span&gt;&lt;br /&gt;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!&lt;br /&gt;&lt;!--&lt;br /&gt;{\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Consolas;}}{\colortbl;??\red0\green0\blue255;\red225\green225\blue225;\red0\green0\blue0;\red0\green128\blue0;\red163\green21\blue21;}??\fs20 \cf1\cb2\highlight2 if\cf0  (document.getElementById) \{ \cf4 //check the browser supports getElementById\par ??\cf0 \tab \cf1 var\cf0  myElement = document.getElementById(\cf5 "myElement"\cf0 );\par ??\tab \cf1 if\cf0  (myElement) \{ \cf4 //check an element was found\par ??\cf0 \tab \tab \cf4 //perform some action\par ??\cf0 \tab \}\par ??\}}&lt;br /&gt;--&gt;&lt;br /&gt;&lt;div style="font-family: Consolas; font-size: 10pt; color: black; background: #e1e1e1; padding:10px;"&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;if&lt;/span&gt; (document.getElementById) { &lt;span style="color: green;"&gt;//check the browser supports getElementById&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;var&lt;/span&gt; myElement = document.getElementById(&lt;span style="color: #a31515;"&gt;"myElement"&lt;/span&gt;);&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;if&lt;/span&gt; (myElement) { &lt;span style="color: green;"&gt;//check an element was found&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;//perform some action&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p style="margin: 0px;"&gt;}&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;8. Lets go native&lt;/span&gt;&lt;br /&gt;Always use native functionality when its there.  Its the fastest method.  If you want to have a &lt;span style="font-style:italic;"&gt;getElementsByClassName&lt;/span&gt; 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.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;9. Delegation's what you need&lt;/span&gt;&lt;br /&gt;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 &lt;a href="http://icant.co.uk/sandbox/eventdelegation/"&gt;see this excellent article&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;10. Get organised&lt;/span&gt;&lt;br /&gt;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 &lt;span style="font-style:italic;"&gt;MyApplication.ApplicationSection.ObjectName&lt;/span&gt;, then I will name the file &lt;span style="font-style:italic;"&gt;MyApplication.ApplicationSection.ObjectName.js&lt;/span&gt;.  In a large application, my folder structure will represent the namespace hierarchy as well.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;11. Dont panic&lt;/span&gt;&lt;br /&gt;Writing JavaScript is hard.  Writing web applications is harder still.  Dont panic.  Help is at hand.  &lt;a href="http://www.j-squared.info/"&gt;Use a library&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8421903615286376978-3840679146639924032?l=nortools.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nortools.blogspot.com/feeds/3840679146639924032/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8421903615286376978&amp;postID=3840679146639924032' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/3840679146639924032'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/3840679146639924032'/><link rel='alternate' type='text/html' href='http://nortools.blogspot.com/2008/05/my-javascript-rules.html' title='My JavaScript &quot;rules&quot;'/><author><name>James Norton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8421903615286376978.post-360680947584783833</id><published>2008-05-24T23:17:00.004+01:00</published><updated>2008-05-27T21:03:07.182+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JSquared'/><title type='text'>JSquared 1.1 Beta 1</title><content type='html'>Just a quick note to point you to information regarding the release of &lt;a href="http://blog.j-squared.info/2008/05/jsquared-11-beta-1.html"&gt;JSquared 1.1 Beta 1&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8421903615286376978-360680947584783833?l=nortools.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nortools.blogspot.com/feeds/360680947584783833/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8421903615286376978&amp;postID=360680947584783833' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/360680947584783833'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/360680947584783833'/><link rel='alternate' type='text/html' href='http://nortools.blogspot.com/2008/05/jsquared-11-beta-1.html' title='JSquared 1.1 Beta 1'/><author><name>James Norton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8421903615286376978.post-8078576710190561198</id><published>2008-05-14T21:45:00.004+01:00</published><updated>2008-05-14T22:02:21.154+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Usability'/><category scheme='http://www.blogger.com/atom/ns#' term='Accessibility'/><title type='text'>Usability and accessibility</title><content type='html'>In recent weeks I have been spending much of my time at work thinking about usability, commenting on it and trying to convince others of my ideas.&lt;br /&gt;&lt;br /&gt;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!&lt;br /&gt;&lt;br /&gt;There were two particular products that I have been looking at, the first of which was &lt;a href="http://www.fiat.co.uk/Content/?id=2590"&gt;a finance tool for Fiat&lt;/a&gt;.  I spent 2 days working on this task and as such was only able to make part of this tool.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;The other product I worked on, was in a similar vein and was a similar success.&lt;br /&gt;&lt;br /&gt;The original project manager on the Fiat project could not tell the difference between the two products and it was entirely cross-browser.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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!&lt;br /&gt;&lt;br /&gt;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.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8421903615286376978-8078576710190561198?l=nortools.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nortools.blogspot.com/feeds/8078576710190561198/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8421903615286376978&amp;postID=8078576710190561198' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/8078576710190561198'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/8078576710190561198'/><link rel='alternate' type='text/html' href='http://nortools.blogspot.com/2008/05/usability.html' title='Usability and accessibility'/><author><name>James Norton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8421903615286376978.post-9155874996173626237</id><published>2008-05-11T18:39:00.002+01:00</published><updated>2008-05-11T18:41:58.709+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JSquared'/><title type='text'>The JSquared blog</title><content type='html'>I am excited to announce the launch of the JSquared blog - &lt;a href="http://blog.j-squared.info/"&gt;http://blog.j-squared.info/&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;I have copied over the relevant posts to the JSquared blog.  Please let me know if you have any comments.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8421903615286376978-9155874996173626237?l=nortools.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nortools.blogspot.com/feeds/9155874996173626237/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8421903615286376978&amp;postID=9155874996173626237' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/9155874996173626237'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/9155874996173626237'/><link rel='alternate' type='text/html' href='http://nortools.blogspot.com/2008/05/jsquared-blog.html' title='The JSquared blog'/><author><name>James Norton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8421903615286376978.post-8092696876969720789</id><published>2008-05-08T23:08:00.002+01:00</published><updated>2008-05-08T23:34:36.872+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JSquared'/><category scheme='http://www.blogger.com/atom/ns#' term='FXSquared'/><title type='text'>JSquared update</title><content type='html'>First of all, apologies for the sparsity of posts in the last few weeks.  Its been a busy couple of weeks, but there is plenty to discuss.  More of that to come in the next week or so.&lt;br /&gt;&lt;br /&gt;The big news however is that JSquared has a new home - &lt;a href="http://www.j-squared.info/"&gt;www.j-squared.info&lt;/a&gt;.  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.&lt;br /&gt;&lt;br /&gt;An update on the progress of the goals for release 1.1:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;JSquared Testing Platform&lt;/span&gt;&lt;br /&gt;Using &lt;a href="http://www.jsunit.net/"&gt;JSUnit&lt;/a&gt;, 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&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Documentation&lt;/span&gt;&lt;br /&gt;Using &lt;a href="http://jsdoctoolkit.org/"&gt;JSDocs&lt;/a&gt;, 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&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;FXSquared&lt;/span&gt;&lt;br /&gt;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&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;IE 8 Beta Support&lt;/span&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;Just to keep you all excited, Chris Heilmann gave a talk at AKQA last week and &lt;a href="http://developer.yahoo.net/blog/archives/2008/05/the_seven_rules.html"&gt;he has posted about it&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8421903615286376978-8092696876969720789?l=nortools.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nortools.blogspot.com/feeds/8092696876969720789/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8421903615286376978&amp;postID=8092696876969720789' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/8092696876969720789'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/8092696876969720789'/><link rel='alternate' type='text/html' href='http://nortools.blogspot.com/2008/05/jsquared-update.html' title='JSquared update'/><author><name>James Norton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8421903615286376978.post-1878698496536142661</id><published>2008-04-27T23:49:00.003+01:00</published><updated>2008-04-28T00:14:16.362+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Browser support'/><category scheme='http://www.blogger.com/atom/ns#' term='Progressive enhancement'/><category scheme='http://www.blogger.com/atom/ns#' term='Web standards'/><category scheme='http://www.blogger.com/atom/ns#' term='CSS'/><title type='text'>Enhancements to CSS</title><content type='html'>&lt;a href="http://ajaxian.com/archives/css-variables-are-next"&gt;This post&lt;/a&gt; presents an interesting idea, that of CSS variables.  On the surface, this could be a brilliant idea, though there are some potential flaws.&lt;br /&gt;&lt;br /&gt;Firstly, there is the issue of redefinition - if a variable is defined and then redefined.  This is particularly pertinent if the variable has been used before it is redefined.&lt;br /&gt;&lt;br /&gt;Then there is the issue of CSS injected via JavaScript.  The final issue I will raise about this is browser support.&lt;br /&gt;&lt;br /&gt;Browser support is an issue which is close to my heart and about which I feel strongly.  I firmly believe that with progressive enhancement, sensible design and tolerance of some differences between browsers from the client, a website can be made to support multiple browsers with minimal effort.&lt;br /&gt;&lt;br /&gt;New innovations are fantastic and should be encouraged, but changes in the CSS specs can cause issues.  We cannot start using this sort of new feature until a major proportion of users are accessing your website with a browser which supports the new feature.&lt;br /&gt;&lt;br /&gt;So, what can we do about this?  It is hard to reconcile the need for general cross-browser support and the desire for improvements and more features in the underlying specifications we use to build websites.&lt;br /&gt;&lt;br /&gt;As I see it, there are a number of things that can be done.  Firstly, we can educate our clients that it is ok for there to be differences.  Secondly, we could build websites in "the classic manner" and also include the CSS style rules introduced by updates to the specification - but this may not work that successfully for obvious reasons.&lt;br /&gt;&lt;br /&gt;As always, us interface developers will generally overcome these issues with a combination of techniques based on the principles of building to web standards and that of progressive enhancement.&lt;br /&gt;&lt;br /&gt;What do you think we can do to overcome these issues?  How can we bring about changes and enhancements as wide ranging as CSS variables without compromising the installed base of users who do not support new features and who can take many years to upgrade?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8421903615286376978-1878698496536142661?l=nortools.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nortools.blogspot.com/feeds/1878698496536142661/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8421903615286376978&amp;postID=1878698496536142661' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/1878698496536142661'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/1878698496536142661'/><link rel='alternate' type='text/html' href='http://nortools.blogspot.com/2008/04/enhancements-to-css.html' title='Enhancements to CSS'/><author><name>James Norton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8421903615286376978.post-395201188945688311</id><published>2008-04-23T17:17:00.005+01:00</published><updated>2008-04-27T23:12:38.381+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='CSS reset'/><category scheme='http://www.blogger.com/atom/ns#' term='Browser support'/><title type='text'>When perfect is not perfect</title><content type='html'>I must recommend &lt;a href="http://withoutsubstance.blogspot.com/2008/04/in-search-of-perfection.html"&gt;this post&lt;/a&gt; by Marcus Alexander.  He moves the argument against pixel perfection - which I have already talked about in a &lt;a href="http://nortools.blogspot.com/2008/04/css-reset-and-pixel-perfection.html"&gt;previous post&lt;/a&gt; - forwards.&lt;br /&gt;&lt;br /&gt;It is my belief that achieving cross browser pixel perfection across a wide range of different browsers costs a project a disproportionate amount of effort and distracts interface developers from the truly important aspects of a website which should be perfect.  I am talking here about minor differences, generally related to the rendering of standard elements - form fields for instance.&lt;br /&gt;&lt;br /&gt;We should be aiming for valid markup, high quality well organised CSS and unobtrusive object oriented JavaScript - we should never have JavaScript errors.  We should be working towards best practices and we should be implementing web standards wherever possible.&lt;br /&gt;&lt;br /&gt;We should be listening to what our clients want and delivering a high quality solution which successfully addresses the problems the client wants solved.  &lt;br /&gt;&lt;br /&gt;However, we should not be expected to work around every single minor layout issue or to change system defaults.  Users understand how their default system controls work, they are inherently usable and accessible.  A user also does not care if a bit of a text is a few pixels out.&lt;br /&gt;&lt;br /&gt;Lets take an example from another aspect of life - television.  Television producers will ensure that their program is executed perfectly with a fantastic script, perfect camera work, flawless sound etc.  However, if you are viewing a program being broadcast in wide screen on a non-wide screen television, you will miss part of the picture - the edges are removed to fit onto the television.  This is a good example as the producer can decide which part of the picture gets cut off.&lt;br /&gt;&lt;br /&gt;I must re-iterate however, that it is vital to produce high quality work which conforms to industry best practices and is accessible to as many users as possible.  There is a big difference between accessible to all users and perfect for all users.&lt;br /&gt;&lt;br /&gt;As Marcus states, no end user of the website is going to be aware of small differences between browsers - and nor should they be.  They will only be unhappy if the website does not operate or is so poorly laid out as to be unusable on their browser of choice.&lt;br /&gt;&lt;br /&gt;I am not suggesting that anything will do.  I am suggesting quite the opposite.  We need to be perfect in most things.  But as long as the differences are small, the basic site layout is not compromised and the full website is usable to all, achieving pixel perfection does not produce the returns its cost surely demands.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8421903615286376978-395201188945688311?l=nortools.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nortools.blogspot.com/feeds/395201188945688311/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8421903615286376978&amp;postID=395201188945688311' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/395201188945688311'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/395201188945688311'/><link rel='alternate' type='text/html' href='http://nortools.blogspot.com/2008/04/when-perfect-is-not-perfect.html' title='When perfect is not perfect'/><author><name>James Norton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8421903615286376978.post-8100028566634871059</id><published>2008-04-22T20:36:00.005+01:00</published><updated>2008-04-27T23:12:26.841+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='AJAX'/><category scheme='http://www.blogger.com/atom/ns#' term='JSquared'/><title type='text'>Asynchronous JavaScript Part 5 - The JSquared AJAX Object</title><content type='html'>In my &lt;a href="http://nortools.blogspot.com/2008/04/asynchronous-javascript-part-4-ajax.html"&gt;previous post in this series&lt;/a&gt;, I introduced some of my thoughts on AJAX.  I will now go into detail as to how to use the &lt;a href="http://code.google.com/p/jsquared/"&gt;JSquared&lt;/a&gt; AJAX object.&lt;br /&gt;&lt;br /&gt;The AJAX object just like &lt;a href="http://nortools.blogspot.com/2008/01/asynchronous-javascript-part-3-using.html"&gt;ADIJ&lt;/a&gt; is an instance based object.  That is to say that for each AJAX request you wish to make, you create an instance of the object and then call a method on it to send the request.  The same object can be reused or new instances can be created.&lt;br /&gt;&lt;br /&gt;The AJAX object will require certain parameters to be provided and generally it is easiest to do so in the constructor, however, the object has methods for setting these values later.&lt;br /&gt;&lt;br /&gt;Only one parameter is required and that is the URL the request is going to.  The full list of parameters is:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;URL&lt;/span&gt; - must be provided either in the constructor or using the &lt;span style="font-style:italic;"&gt;setUrl&lt;/span&gt; method&lt;br /&gt;&lt;span style="font-style:italic;"&gt;method&lt;/span&gt; - the HTTP verb to be used for the request.  Defaults to &lt;span style="font-style:italic;"&gt;GET&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;onSuccess&lt;/span&gt; - the callback function if the request is successful&lt;br /&gt;&lt;span style="font-style:italic;"&gt;onFail&lt;/span&gt; - the callback function if the request fails&lt;br /&gt;&lt;span style="font-style:italic;"&gt;scope&lt;/span&gt; - the scope in which to run the &lt;span style="font-style:italic;"&gt;onSuccess&lt;/span&gt; or &lt;span style="font-style:italic;"&gt;onFail&lt;/span&gt; handler (the scope sets the value of this within the callback function).  Defaults to the handler function itself&lt;br /&gt;&lt;span style="font-style:italic;"&gt;timeoutLength&lt;/span&gt; - the maximum time to wait for a server response to the request before timing out the request and calling the onFail handler. Defaults to 12 seconds&lt;br /&gt;&lt;span style="font-style:italic;"&gt;headers&lt;/span&gt; - an array of objects containing &lt;span style="font-style:italic;"&gt;key&lt;/span&gt; and &lt;span style="font-style:italic;"&gt;value&lt;/span&gt; pairs which are the additional headers to add to the request&lt;br /&gt;&lt;br /&gt;Each of these parameters can be set once the object is created using a method.&lt;br /&gt;&lt;br /&gt;To send the request, simply call the &lt;span style="font-style:italic;"&gt;send&lt;/span&gt; method:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: consolas, courier new; font-size: 9pt; color: black; background: #e1e1e1; padding:10px;"&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;var&lt;/span&gt; myAjaxRequest = &lt;span style="color: blue;"&gt;new&lt;/span&gt; J2.AJAX( {url: &lt;span style="color: #a31515;"&gt;"myAJAXUrl.html"&lt;/span&gt;} );&lt;/p&gt;&lt;p style="margin: 0px;"&gt;myAjaxRequest.send();&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;The send method accepts an argument which is the string of data to add to the request.  This argument is optional.&lt;br /&gt;&lt;br /&gt;As you can clearly see, the parameters are passed into the constructor as a JavaScript object using object notation.&lt;br /&gt;&lt;br /&gt;If you provide an &lt;span style="font-style:italic;"&gt;onSuccess&lt;/span&gt; handler, that will be called if the request completes successfully and will have the AJAX object passed in as the first argument to the function.  This will allow all the properties of the request to be accessed.&lt;br /&gt;&lt;br /&gt;If the request should fail, the &lt;span style="font-style:italic;"&gt;onFail&lt;/span&gt; handler will be called.  The first argument passed to the fail handler is the AJAX object.  The second argument will be the failure code.  The code can then be examined by comparing it against the value of the AJAX failure codes object which looks as follows:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: consolas, courier new; font-size: 9pt; color: black; background: #e1e1e1; padding:10px;"&gt;&lt;p style="margin: 0px;"&gt;J2.AJAX.FailureCodes = {&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; general: &lt;span style="color: #a31515;"&gt;"xx1"&lt;/span&gt;,&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; unauthorised: 401,&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; notFound: 404,&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; timeout: 408,&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; server: 500&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/p&gt;&lt;p style="margin: 0px;"&gt;}&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;If you do not provide an &lt;span style="font-style:italic;"&gt;onSuccess&lt;/span&gt; or &lt;span style="font-style:italic;"&gt;onFail&lt;/span&gt; handler, then the object will simply do nothing - there will be no error shown.&lt;br /&gt;&lt;br /&gt;Once again, I have to say that it is as simple as that.  This is a really powerful but easy to use AJAX object.&lt;br /&gt;&lt;br /&gt;This is the end of the series on Asynchronous JavaScript.  I will be writing more about the other features of &lt;a href="http://code.google.com/p/jsquared/"&gt;JSquared&lt;/a&gt; in the near future.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8421903615286376978-8100028566634871059?l=nortools.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nortools.blogspot.com/feeds/8100028566634871059/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8421903615286376978&amp;postID=8100028566634871059' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/8100028566634871059'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/8100028566634871059'/><link rel='alternate' type='text/html' href='http://nortools.blogspot.com/2008/04/asynchronous-javascript-part-5-jsquared.html' title='Asynchronous JavaScript Part 5 - The JSquared AJAX Object'/><author><name>James Norton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8421903615286376978.post-3812288190276954848</id><published>2008-04-21T16:20:00.004+01:00</published><updated>2008-04-27T23:12:17.041+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JSquared'/><title type='text'>JSquared road map and update</title><content type='html'>I have literally been swamped by a request for a road map for &lt;a href="http://code.google.com/p/jsquared/"&gt;JSquared&lt;/a&gt;.  In response, I have created &lt;a href="http://code.google.com/p/jsquared/wiki/Roadmap"&gt;this wiki page&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I have some ambitious plans for JSquared and it may not all be possible - much depends on how much my wife puts up with me working late into the night.  But my aims are stated there.&lt;br /&gt;&lt;br /&gt;I will be releasing periodic compatibility updates in between these major releases.&lt;br /&gt;&lt;br /&gt;The single most requested feature for JSquared thus far is documentation and it is high on my priority list.  I am intending on providing this as a set of object models output  using JSDocs and an accompanying guide.  Following that, I hope to be able to get a JSquared website up and running full of example code.&lt;br /&gt;&lt;br /&gt;A set of unit tests and indeed a full testing platform for JSquared is also very high on the priority list and progress is being made on this.  The intention for JSquared 1.1 is to get the core functions unit tested.&lt;br /&gt;&lt;br /&gt;FXSquared is making good progress with a basic FX module ready for some heavy duty testing.  FXSquared is built around plugins to allow for maximum flexibility.&lt;br /&gt;&lt;br /&gt;IE 8 support continues to improve with each commit of the code.  I expect IE 8 support to match that of all other browsers for JSquared 1.1&lt;br /&gt;&lt;br /&gt;Please use this post or the wiki on the current &lt;a href="http://code.google.com/p/jsquared/"&gt;JSquared home&lt;/a&gt; to comment on the road map, especially the form that the documentation should take.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8421903615286376978-3812288190276954848?l=nortools.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nortools.blogspot.com/feeds/3812288190276954848/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8421903615286376978&amp;postID=3812288190276954848' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/3812288190276954848'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/3812288190276954848'/><link rel='alternate' type='text/html' href='http://nortools.blogspot.com/2008/04/jsquared-road-map-and-update.html' title='JSquared road map and update'/><author><name>James Norton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8421903615286376978.post-2307622921084308129</id><published>2008-04-17T10:02:00.005+01:00</published><updated>2008-04-27T23:12:09.950+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='CSS reset'/><category scheme='http://www.blogger.com/atom/ns#' term='CSS'/><title type='text'>CSS reset and pixel perfection</title><content type='html'>&lt;a href="http://snook.ca/archives/html_and_css/no_css_reset/#c"&gt;This recent post&lt;/a&gt; from Jonathan Snook nicely sums up my feeling on CSS reset files.&lt;br /&gt;&lt;br /&gt;I have often argued that CSS reset files will end up causing more problems than they solve.  Indeed, I am not convinced they solve a real problem.&lt;br /&gt;&lt;br /&gt;The problem seems to be that each browser I support does not apply the same default styling to some elements that I may use in my website.&lt;br /&gt;&lt;br /&gt;The solution proposed by CSS reset files is to create a base line set of CSS rules which will on first inspection solve this problem.  However, I am not sure I agree that the problem is as stated above.&lt;br /&gt;&lt;br /&gt;I believe the problem is that each website I code looks and behaves differently and does not use the same set of default styles as other websites I have developed.&lt;br /&gt;&lt;br /&gt;The solution I propose is resetting only the CSS styles I actually need in order to make the website look correct in as few styles as possible.  Only then will I be interested in the difference between browsers.  I would still use the * reset myself as I find that generally is useful and makes a fairly large difference when designing my CSS.  I would not employ any more of a reset than that.&lt;br /&gt;&lt;br /&gt;As an example, my website may not use any level 3 headings.  In that instance, my CSS code will not try and select any 3rd level headings at all.  If later during development I need to use a level 3 heading, I will use the tag and add the relevant CSS code.  I have always employed this approach and it has so far never let me down.&lt;br /&gt;&lt;br /&gt;For more details on my approach to structuring CSS, I suggest reading &lt;a href="http://nortools.blogspot.com/2008/01/structured-css.html"&gt;this post&lt;/a&gt;. Of course ideas change over time, but it is still relevant.&lt;br /&gt;&lt;br /&gt;I always believe in code being as lightweight as possible, not purely for speed of download but for ease of maintenance and the retention of my own sanity!&lt;br /&gt;&lt;br /&gt;The other point raised by the &lt;a href="http://snook.ca/archives/html_and_css/no_css_reset/#c"&gt;post&lt;/a&gt; I mention above is that of producing cross-browser pixel perfect layouts.  This is a topic that probably deserves its own post if not a series of posts, however, I rarely strive for pixel perfection.  I just do not believe it is that important any more.  I would argue that users are becoming aware that websites will look very slightly different on different platforms.  I definitely did not perfectly explain my position in &lt;a href="http://nortools.blogspot.com/2007/12/browser-support.html"&gt;my previous post about browser support&lt;/a&gt; so I will clarify it here.&lt;br /&gt;&lt;br /&gt;In that post, for level 1 browsers (the only relevant browsers in this discussion) I state:&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;All features of the website are fully functional. All content is available. The web pages will match the designs provided completely. The web pages will look the same across all browsers at this level.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;What I should have said was:&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;All features of the website are fully functional. All content is available. The web pages will match the designs provided completely &lt;span style="font-weight:bold;"&gt;with the exception of system entities such as form fields and rendered fonts which may cause a layout to differ slightly&lt;/span&gt;. The web pages will look the same across all browsers at this level &lt;span style="font-weight:bold;"&gt;within the constraints of the different rendering methods for each platform&lt;/span&gt;.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;That more fully expresses how I feel about pixel perfection.  Sometimes it can be done, sometimes it cannot.  We should educate our clients that pixel perfection is not always important.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8421903615286376978-2307622921084308129?l=nortools.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nortools.blogspot.com/feeds/2307622921084308129/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8421903615286376978&amp;postID=2307622921084308129' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/2307622921084308129'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/2307622921084308129'/><link rel='alternate' type='text/html' href='http://nortools.blogspot.com/2008/04/css-reset-and-pixel-perfection.html' title='CSS reset and pixel perfection'/><author><name>James Norton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8421903615286376978.post-6954698180877241808</id><published>2008-04-09T13:34:00.004+01:00</published><updated>2008-04-27T23:11:24.102+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><title type='text'>WOW - Seriously</title><content type='html'>I saw &lt;a href="http://ajaxian.com/archives/super-mario-14kb-of-javascript"&gt;this post&lt;/a&gt; on Ajaxian and could not resist posting it here myself.&lt;br /&gt;&lt;br /&gt;It is truly quite awesome!&lt;br /&gt;&lt;br /&gt;&lt;a href="http://blog.nihilogic.dk/2008/04/super-mario-in-14kb-javascript.html"&gt;Super Mario in 14Kb of JavaScript&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8421903615286376978-6954698180877241808?l=nortools.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nortools.blogspot.com/feeds/6954698180877241808/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8421903615286376978&amp;postID=6954698180877241808' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/6954698180877241808'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/6954698180877241808'/><link rel='alternate' type='text/html' href='http://nortools.blogspot.com/2008/04/wow-seriously.html' title='WOW - Seriously'/><author><name>James Norton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8421903615286376978.post-1245437144200297453</id><published>2008-04-08T17:00:00.003+01:00</published><updated>2008-04-27T23:11:16.309+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='CSS'/><category scheme='http://www.blogger.com/atom/ns#' term='Accessibility'/><title type='text'>outline:0</title><content type='html'>There is nothing more annoying for those who wish to navigate a website using the keyboard than the extensive use of outline:0 in &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;CSS&lt;/span&gt; code.  For a more detailed explanation of what this is and what it means, &lt;a href="http://webaim.org/blog/plague-of-outline-0/"&gt;I suggest you read this blog post&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Although I luckily do not suffer from any form of disability and do not actually require any effort to be made by a web developer towards accessibility, I do like to browse using the keyboard on &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_1"&gt;occasion&lt;/span&gt; and this can be a highly frustrating problem.&lt;br /&gt;&lt;br /&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;CSS&lt;/span&gt; reset files such as the one mentioned in the post can leave developers without a full understanding of the nuances of the platform they are developing for.  It is at least in part for this reason that I &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;dont&lt;/span&gt; use a &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;CSS&lt;/span&gt; reset at all.&lt;br /&gt;&lt;br /&gt;My message to all would be to not  remove this extremely useful and built-in behavior but actually to enhance it.  Try navigation the &lt;a href="http://www.london2012.com/"&gt;London 2012 website &lt;/a&gt;with the keyboard (a site I led the development on) to see how nice it is to have the outline behaviour enhanced rather than removed.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8421903615286376978-1245437144200297453?l=nortools.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nortools.blogspot.com/feeds/1245437144200297453/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8421903615286376978&amp;postID=1245437144200297453' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/1245437144200297453'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/1245437144200297453'/><link rel='alternate' type='text/html' href='http://nortools.blogspot.com/2008/04/outline0.html' title='outline:0'/><author><name>James Norton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8421903615286376978.post-2451353412225910714</id><published>2008-04-07T23:12:00.003+01:00</published><updated>2008-04-27T23:11:07.446+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JSquared'/><title type='text'>Documenting JSquared</title><content type='html'>One of the biggest missing aspects from &lt;a href="http://code.google.com/p/jsquared/"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;JSquared&lt;/span&gt; &lt;/a&gt;is documentation.&lt;br /&gt;&lt;br /&gt;I have been looking at using an automated tool to build documentation from comments in the code (another thing which is currently lacking) and this is going to be a major push for me over the next 2 months. &lt;br /&gt;&lt;br /&gt;I have almost settled on using &lt;a href="http://jsdoc.sourceforge.net/"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;JSDoc&lt;/span&gt;&lt;/a&gt;.  I would be very thankful if the readers of this blog could give any thoughts on &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;JSDoc&lt;/span&gt; or any alternatives that I should be looking at.&lt;br /&gt;&lt;br /&gt;Thanks in advance.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8421903615286376978-2451353412225910714?l=nortools.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nortools.blogspot.com/feeds/2451353412225910714/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8421903615286376978&amp;postID=2451353412225910714' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/2451353412225910714'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/2451353412225910714'/><link rel='alternate' type='text/html' href='http://nortools.blogspot.com/2008/04/documenting-jsquared.html' title='Documenting JSquared'/><author><name>James Norton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8421903615286376978.post-3656368278948174791</id><published>2008-04-07T22:55:00.005+01:00</published><updated>2008-04-27T23:11:00.603+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Browser support'/><category scheme='http://www.blogger.com/atom/ns#' term='JSquared'/><title type='text'>Safari 3.1 and IE8 Beta 1 support in JSquared</title><content type='html'>With the release of Safari 3.1 on PC and MAC, the handling of keyboard events has changed as detailed in &lt;a href="http://ajaxian.com/archives/key-events-and-safari-31"&gt;this post on &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;Ajaxian&lt;/span&gt;&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I am delighted to say that the &lt;a href="http://nortools.blogspot.com/2008/02/jsquared-auto-filter-list.html"&gt;auto filter object&lt;/a&gt; in &lt;a href="http://code.google.com/p/jsquared/"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;JSquared&lt;/span&gt; 1.0&lt;/a&gt; is fully compliant with Safari 3.1 and no changes to the code are required.  This is the only object in &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;JSquared&lt;/span&gt; with keyboard handling at present.&lt;br /&gt;&lt;br /&gt;The big news recently though is the release of &lt;a href="http://blogs.msdn.com/ie/archive/2008/04/07/ie8-beta-1-for-developers-now-available-in-chinese-simplified-and-german.aspx"&gt;IE8 Beta 1&lt;/a&gt;.  I am currently testing &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;JSquared&lt;/span&gt; with this release and things are looking good.  I expect there to be some minor changes to the code which will precipitate the release of a &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;JSquared&lt;/span&gt; &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_5"&gt;compatibility&lt;/span&gt; update.  More news on this in the next few weeks.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8421903615286376978-3656368278948174791?l=nortools.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nortools.blogspot.com/feeds/3656368278948174791/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8421903615286376978&amp;postID=3656368278948174791' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/3656368278948174791'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/3656368278948174791'/><link rel='alternate' type='text/html' href='http://nortools.blogspot.com/2008/04/safari-31-and-ie8-beta-1-support-in.html' title='Safari 3.1 and IE8 Beta 1 support in JSquared'/><author><name>James Norton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8421903615286376978.post-6270492993868595520</id><published>2008-04-05T23:47:00.004+01:00</published><updated>2008-04-27T23:10:50.295+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='AJAX'/><title type='text'>Asynchronous JavaScript Part 4 - AJAX (a quick introduction)</title><content type='html'>In the previous 3 parts of this series on asynchronous JavaScript, I have talked at length about ADIJ.  I suggest starting at &lt;a href="http://nortools.blogspot.com/2008/01/asynchronous-javascript-part-1-adij.html"&gt;part 1&lt;/a&gt; to catch up!&lt;br /&gt;&lt;br /&gt;AJAX is a term which has been bastardised to describe any sort of interactive behaviour in a web page.  A number of years ago, these interactions were known as dHTML (dynamic HTML).  Neither AJAX nor dHTML perfectly describe these types of interactions, but I prefer the latter name.&lt;br /&gt;&lt;br /&gt;AJAX to me should mean &lt;span style="font-weight: bold;"&gt;Asynchronous JavaScript and XML.&lt;/span&gt;  This is not perfect as it is often the case that XML is not appropriate and sometimes JavaScript, &lt;a href="http://www.json.org/"&gt;JSON, &lt;/a&gt;HTML or even plain text is required instead.  Nonetheless, the acronym AJAX still has one definite meaning to me! &lt;br /&gt;&lt;br /&gt;For the purposes of this post and the remainder of this series I will use it to mean any form of asynchronous HTTP request whose response will be handled using JavaScript code whatever form that response takes.&lt;br /&gt;&lt;br /&gt;AJAX is a very useful and powerful technique invented by Microsoft for Outlook Web Access  and later adopted by other browser vendors.  When used in a fairly light touch manner, AJAX techniques can give the user a greatly enhanced experience.&lt;br /&gt;&lt;br /&gt;AJAX involves sending an HTTP request to a web server and getting a response asynchronously which is handled in JavaScript.  This means more data can be requested from the server or passed to the server without the user seeing the web page refresh.&lt;br /&gt;&lt;br /&gt;An asynchronous request happens in the background - it allows other operations to be performed whilst the HTTP cycle is completed.  You provide a callback function to the AJAX object which is called once the HTTP cycle is complete.  I wont go into more detail around implementation and what it all means as there are many excellent tutorials already written.  The W3Schools has &lt;a href="http://www.w3schools.com/AJAX/default.asp"&gt;one of their own.&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.w3schools.com/AJAX/default.asp"&gt;&lt;br /&gt;&lt;/a&gt;Using AJAX it is possible do things such as post a form or update the content of a web page without the user going through a page refresh cycle.  This makes the web page seem more like an application and can make it better for users to interact with.&lt;br /&gt;&lt;br /&gt;Of course, &lt;a href="http://code.google.com/p/jsquared/"&gt;JSquared&lt;/a&gt; has an AJAX component which is extremely simple to use yet offers flexibility and power.  In part 5 of this series, I will walk through the AJAX object and then discuss how to use it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8421903615286376978-6270492993868595520?l=nortools.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nortools.blogspot.com/feeds/6270492993868595520/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8421903615286376978&amp;postID=6270492993868595520' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/6270492993868595520'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/6270492993868595520'/><link rel='alternate' type='text/html' href='http://nortools.blogspot.com/2008/04/asynchronous-javascript-part-4-ajax.html' title='Asynchronous JavaScript Part 4 - AJAX (a quick introduction)'/><author><name>James Norton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8421903615286376978.post-7569222791458540552</id><published>2008-04-03T08:56:00.003+01:00</published><updated>2008-04-27T23:10:12.401+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Browser support'/><category scheme='http://www.blogger.com/atom/ns#' term='Browsers'/><title type='text'>Future proofing</title><content type='html'>With updates to some of the most popular and widely used browsers soon to appear - namely IE 8 and Firefox 3 - the question has to be posed about how and when to support them.&lt;br /&gt;&lt;br /&gt;It is a fairly simple matter to test your websites in the new versions of these browsers as there are beta versions of both available, however, it can be very time-consuming to fix issues and clients can find it a bitter pill to swallow.&lt;br /&gt;&lt;br /&gt;The biggest problem here is a lack of overall transparency about how and when these browsers will be released.  This issue is much much greater where IE is concerned.&lt;br /&gt;&lt;br /&gt;We know that Firefox is slated for a June release and it is likely that the automatic update system will offer users the new version.  It is therefore reasonable to suppose that there will be a fairly rapid surge in the number of users for Firefox 3.&lt;br /&gt;&lt;br /&gt;As far as IE is concerned, we cannot be sure of a release date or the mechanism by which the update will be delivered.  It is possible that there will be a split between IE 7 and IE 8 users for some time until IE 8 is pushed through automatic updates as a high priority update.  This in a way is what has happened with the IE 6 to IE 7 transition.&lt;br /&gt;&lt;br /&gt;I think it is reasonable for an interface developer to support 2 versions of a popular web browser (perhaps at different &lt;a href="http://nortools.blogspot.com/2007/12/browser-support.html"&gt;levels of support&lt;/a&gt;), but I do not like the idea of having to support 3 versions at any level, particularly when one of those is IE 6!&lt;br /&gt;&lt;br /&gt;So, the question is, what to do?  I am unsure at the moment, though I am considering testing my websites in Firefox 3 as of now and attempting a good level of support.  As far as IE 8 goes, if its IE 7 mode works well, then that is a very good reason to not support IE 8 until it is actually released.&lt;br /&gt;&lt;br /&gt;If Microsoft released a road map with release dates for IE 8 and the version afterwards, then I could plan my browser support strategy much more easily.  So come on Microsoft, talk to me....&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8421903615286376978-7569222791458540552?l=nortools.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nortools.blogspot.com/feeds/7569222791458540552/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8421903615286376978&amp;postID=7569222791458540552' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/7569222791458540552'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/7569222791458540552'/><link rel='alternate' type='text/html' href='http://nortools.blogspot.com/2008/04/future-proofing.html' title='Future proofing'/><author><name>James Norton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8421903615286376978.post-1262699811653443713</id><published>2008-03-31T20:43:00.018+01:00</published><updated>2008-12-11T23:22:14.218Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Progressive enhancement'/><category scheme='http://www.blogger.com/atom/ns#' term='CSS'/><title type='text'>Progressive degradation</title><content type='html'>I should start this post with a disclaimer.  I did not discover or invent this technique.  It was suggested to me by a now ex-colleague, Marcus.  He also does not like what I have named this technique.  But you can make your own mind up.&lt;br /&gt;&lt;br /&gt;We should by now all be aware of &lt;a href="http://nortools.blogspot.com/2007/12/progressive-enhancement.html"&gt;progressive enhancement&lt;/a&gt;, what it is and why to use it.  Well, progressive degradation actually assists with progressive enhancement and in some ways turns the idea on its head to make life easier and simpler.  Whenever I have employed progressive degradation, I have found things easier to develop and maintain.&lt;br /&gt;&lt;br /&gt;Progressive enhancement generally involves writing high quality semantic markup and then layering onto that additional elements which do not in themselves add additional meaning but enhance the visual presentation of the content of a web page or make it easier and nicer to use.&lt;br /&gt;&lt;br /&gt;Generally progressive enhancement will mean layering CSS on to the markup to make the web page look nice, and JavaScript to make the web page easier and nicer to use.  Progressive degradation turns that idea on its head.&lt;br /&gt;&lt;br /&gt;With progressive degradation, we still need high quality semantic markup.  That is always the base.  We are still going to layer CSS on to the markup to make the web page look nice.  The big change is with the JavaScript.&lt;br /&gt;&lt;br /&gt;Using progressive enhancement, we would write the CSS in such a way that if the user does not have a JavaScript enabled browser, the site works well and looks correct.  If the user does have a JavaScript enabled browser, the JavaScript code itself would make changes to the way the CSS is applied (and perhaps to the markup as well) to give the web pages a slightly different look and additional behaviours.&lt;br /&gt;&lt;br /&gt;Using progressive degradation, we apply the CSS to the markup in the assumption that the user has a JavaScript enabled browser.  Let me just make that clear.  We make the assumption that the user has JavaScript enabled within their browser.&lt;br /&gt;&lt;br /&gt;So where is the magic?  The trick is that we include an additional CSS file for those users who DO NOT have JavaScript enabled in their browser which will re-style the content to be usable without the JavaScript enhancements.&lt;br /&gt;&lt;br /&gt;This technique is not suitable for all occasions, but when I have employed it within a website, I have found a way to use it for every enhanced element.&lt;br /&gt;&lt;br /&gt;The major advantage of progressive degradation is that there is no page flicker as the content is altered by JavaScript code even when the JavaScript code is run on page load as the CSS code that is loaded with the page sets up the page for the JavaScript enhanced version from load.&lt;br /&gt;&lt;br /&gt;Its an extremely simple technique to apply and the following code is all you need:&lt;br /&gt;&lt;br /&gt;&lt;div    style="background: rgb(234, 234, 196) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;font-family:Courier New;font-size:10pt;color:black;padding:10px;"&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:maroon;"&gt;noscript&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color:blue;"&gt;    &amp;lt;&lt;/span&gt;&lt;span style="color:maroon;"&gt;link&lt;/span&gt;&lt;span style="color:fuchsia;"&gt; &lt;/span&gt;&lt;span style="color:red;"&gt;rel&lt;/span&gt;&lt;span style="color:blue;"&gt;="stylesheet"&lt;/span&gt;&lt;span style="color:fuchsia;"&gt; &lt;/span&gt;&lt;span style="color:red;"&gt;href&lt;/span&gt;&lt;span style="color:blue;"&gt;="noscript.css"&lt;/span&gt;&lt;span style="color:fuchsia;"&gt; &lt;/span&gt;&lt;span style="color:red;"&gt;type&lt;/span&gt;&lt;span style="color:blue;"&gt;="text/css"&lt;/span&gt;&lt;span style="color:fuchsia;"&gt; &lt;/span&gt;&lt;span style="color:red;"&gt;media&lt;/span&gt;&lt;span style="color:blue;"&gt;="screen"&lt;/span&gt;&lt;span style="color:fuchsia;"&gt; &lt;/span&gt;&lt;span style="color:blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:maroon;"&gt;noscript&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;As you can see, all that is involved is the addition of a CSS file inside noscript tags.  Whilst this does make the markup for your web page invalid, I believe it is a small price to pay for the power it brings.  To demonstrate that power, an example could be useful.&lt;br /&gt;&lt;br /&gt;The example I will use is that of a form which will add an item to a list.  Without JavaScript, the form will always be visible.  With JavaScript, there will be an add button which when clicked will show the form.  How the form submission is handled here is not important but one could use an AJAX request for those user agents which support it and a postback cycle for those which do not.&lt;br /&gt;&lt;br /&gt;The 2 versions of this page element look as follows:&lt;br /&gt;&lt;br /&gt;With JavaScript enabled:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_MYZ44Y8H5KI/R_FNX8HPy1I/AAAAAAAAAA8/cWfIcxgdqw8/s1600-h/js-version.gif"&gt;&lt;img style="cursor: pointer;" src="http://2.bp.blogspot.com/_MYZ44Y8H5KI/R_FNX8HPy1I/AAAAAAAAAA8/cWfIcxgdqw8/s320/js-version.gif" alt="" id="BLOGGER_PHOTO_ID_5184009719749004114" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Without JavaScipt enabled:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_MYZ44Y8H5KI/R_FNyMHPy2I/AAAAAAAAABE/p2rXZ3pAp9Y/s1600-h/non-js-version.gif"&gt;&lt;img style="cursor: pointer;" src="http://3.bp.blogspot.com/_MYZ44Y8H5KI/R_FNyMHPy2I/AAAAAAAAABE/p2rXZ3pAp9Y/s320/non-js-version.gif" alt="" id="BLOGGER_PHOTO_ID_5184010170720570210" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The markup is as follows:&lt;br /&gt;&lt;br /&gt;&lt;div    style="padding:10px;background: rgb(234, 234, 196) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;font-family:Courier New;font-size:10pt;color:black;"&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:maroon;"&gt;div&lt;/span&gt;&lt;span style="color:fuchsia;"&gt; &lt;/span&gt;&lt;span style="color:red;"&gt;id&lt;/span&gt;&lt;span style="color:blue;"&gt;="ListContainer"&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;    &lt;span style="color:blue;"&gt;    &amp;lt;&lt;/span&gt;&lt;span style="color:maroon;"&gt;ul&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;        &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:maroon;"&gt;li&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;span style=""&gt;Item 1&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:maroon;"&gt;li&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style=""&gt;        &lt;/span&gt;        &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:maroon;"&gt;li&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;span style=""&gt;Item 2&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:maroon;"&gt;li&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;    &lt;span style=""&gt;    &lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:maroon;"&gt;ul&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;    &lt;span style=""&gt;    &lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:maroon;"&gt;form&lt;/span&gt;&lt;span style="color:fuchsia;"&gt; &lt;/span&gt;&lt;span style="color:red;"&gt;action&lt;/span&gt;&lt;span style="color:blue;"&gt;="page.html"&lt;/span&gt;&lt;span style="color:fuchsia;"&gt; &lt;/span&gt;&lt;span style="color:red;"&gt;method&lt;/span&gt;&lt;span style="color:blue;"&gt;="post"&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;        &lt;span style=""&gt;        &lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:maroon;"&gt;label&lt;/span&gt;&lt;span style="color:fuchsia;"&gt; &lt;/span&gt;&lt;span style="color:red;"&gt;for&lt;/span&gt;&lt;span style="color:blue;"&gt;="NewItem"&lt;/span&gt;&lt;span style="color:fuchsia;"&gt; &lt;/span&gt;&lt;span style="color:red;"&gt;id&lt;/span&gt;&lt;span style="color:blue;"&gt;="NewItemLabel"&amp;gt;&lt;/span&gt;&lt;span style=""&gt;Add item&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:maroon;"&gt;label&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;        &lt;span style=""&gt;        &lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:maroon;"&gt;input&lt;/span&gt;&lt;span style="color:fuchsia;"&gt; &lt;/span&gt;&lt;span style="color:red;"&gt;id&lt;/span&gt;&lt;span style="color:blue;"&gt;="NewItem"&lt;/span&gt;&lt;span style="color:fuchsia;"&gt; &lt;/span&gt;&lt;span style="color:red;"&gt;type&lt;/span&gt;&lt;span style="color:blue;"&gt;="text"&lt;/span&gt;&lt;span style="color:fuchsia;"&gt; &lt;/span&gt;&lt;span style="color:blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;        &lt;span style=""&gt;        &lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:maroon;"&gt;input&lt;/span&gt;&lt;span style="color:fuchsia;"&gt; &lt;/span&gt;&lt;span style="color:red;"&gt;type&lt;/span&gt;&lt;span style="color:blue;"&gt;="submit"&lt;/span&gt;&lt;span style="color:fuchsia;"&gt; &lt;/span&gt;&lt;span style="color:red;"&gt;id&lt;/span&gt;&lt;span style="color:blue;"&gt;="SubmitForm"&lt;/span&gt;&lt;span style="color:fuchsia;"&gt; &lt;/span&gt;&lt;span style="color:red;"&gt;value&lt;/span&gt;&lt;span style="color:blue;"&gt;="add"&lt;/span&gt;&lt;span style="color:fuchsia;"&gt; &lt;/span&gt;&lt;span style="color:blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;    &lt;span style=""&gt;    &lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:maroon;"&gt;form&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:maroon;"&gt;div&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;The pertinent CSS for the purposes of this article is:&lt;br /&gt;&lt;div    style="padding:10px;background: rgb(234, 234, 196) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;font-family:Courier New;font-size:10pt;color:black;"&gt;&lt;span style="color:maroon;"&gt;#NewItem&lt;/span&gt;&lt;span style=""&gt;, &lt;/span&gt;&lt;span style="color:maroon;"&gt;#SubmitForm&lt;/span&gt;&lt;span style=""&gt; {&lt;/span&gt;&lt;p style="margin: 0px;"&gt;&lt;span style=""&gt;    &lt;/span&gt;&lt;span style="color:red;"&gt;display&lt;/span&gt;&lt;span style=""&gt;:&lt;/span&gt;&lt;span style="color:blue;"&gt;none&lt;/span&gt;&lt;span style=""&gt;;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style=""&gt;}&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;This CSS will hide the input field and the submit button.&lt;br /&gt;&lt;br /&gt;The following (somewhat rough) JavaScript will make the progressive enhancement work so that when clicking on the label for the form field, the input field and submit button will show:&lt;br /&gt;&lt;div    style="padding:10px;background: rgb(234, 234, 196) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;font-family:Courier New;font-size:10pt;color:black;"&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:maroon;"&gt;script&lt;/span&gt;&lt;span style="color:fuchsia;"&gt; &lt;/span&gt;&lt;span style="color:red;"&gt;type&lt;/span&gt;&lt;span style="color:blue;"&gt;="text/javascript"&amp;gt;&lt;/span&gt;&lt;p style="margin: 0px;"&gt;&lt;span style=""&gt;    window.onload = &lt;/span&gt;&lt;span style="color:blue;"&gt;function&lt;/span&gt;&lt;span style=""&gt;() {&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style=""&gt;        document.getElementById("NewItemLabel").onclick = &lt;/span&gt;&lt;span style="color:blue;"&gt;function&lt;/span&gt;&lt;span style=""&gt;() {&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style=""&gt;            &lt;/span&gt;&lt;span style="color:blue;"&gt;this&lt;/span&gt;&lt;span style=""&gt;.style.display = "none";&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style=""&gt;            document.getElementById("NewItem").style.display = "block";&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style=""&gt;            document.getElementById("SubmitForm").style.display = "block";&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style=""&gt;        }&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style=""&gt;    }&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:maroon;"&gt;script&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;So, we now have a working form module as described above.  When the page loads, some elements are hidden - there is no flicker whilst the JavaScript kicks in on page load and hides the relevant elements as they are already hidden!  Clicking on the label will hide the label and show the relevant elements.&lt;br /&gt;&lt;br /&gt;Now for the progressive degradation:&lt;br /&gt;&lt;div    style="padding:10px;background: rgb(234, 234, 196) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;font-family:Courier New;font-size:10pt;color:black;"&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:maroon;"&gt;noscript&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style=""&gt;    &lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:maroon;"&gt;style&lt;/span&gt;&lt;span style="color:fuchsia;"&gt; &lt;/span&gt;&lt;span style="color:red;"&gt;type&lt;/span&gt;&lt;span style="color:blue;"&gt;="text/css"&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style=""&gt;        &lt;/span&gt;&lt;span style="color:maroon;"&gt;#NewItem&lt;/span&gt;&lt;span style=""&gt;, &lt;/span&gt;&lt;span style="color:maroon;"&gt;#SubmitForm&lt;/span&gt;&lt;span style=""&gt; {&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style=""&gt;            &lt;/span&gt;&lt;span style="color:red;"&gt;display&lt;/span&gt;&lt;span style=""&gt;:&lt;/span&gt;&lt;span style="color:blue;"&gt;block&lt;/span&gt;&lt;span style=""&gt;;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style=""&gt;        }&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style=""&gt;    &lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:maroon;"&gt;style&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:maroon;"&gt;noscript&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;And that is all there is to it.  Without JavaScript enabled in the web browser, the user will see the complete form.  With JavaScript enabled, the user gets an enhanced experience.  If you re-read the last 2 sentences, you will notice how right it sounds and yet we are mixing the concepts of progressive enhancement with those of progressive degradation.&lt;br /&gt;&lt;br /&gt;Of course we could take this example much further, writing some JavaScript to allow the user to return the page to its load state if they changed their mind and did not actually want to add another list item.  We could write code to handle the form submission etc and all this would be progressive enhancement, but progressive enhancement made even easier by starting with the concept of progressive degradation.&lt;br /&gt;&lt;br /&gt;The key to how progressive degradation makes this easier is that we know the non-JavaScript version of the page will work perfectly and we can add as much progressive enhancement as we like and concentrate on writing fantastic JavaScript to enable exciting but as always simple and light-touch enhancements to the web pages we build.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8421903615286376978-1262699811653443713?l=nortools.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nortools.blogspot.com/feeds/1262699811653443713/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8421903615286376978&amp;postID=1262699811653443713' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/1262699811653443713'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/1262699811653443713'/><link rel='alternate' type='text/html' href='http://nortools.blogspot.com/2008/03/progressive-degradation.html' title='Progressive degradation'/><author><name>James Norton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_MYZ44Y8H5KI/R_FNX8HPy1I/AAAAAAAAAA8/cWfIcxgdqw8/s72-c/js-version.gif' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8421903615286376978.post-2398466842745424512</id><published>2008-03-24T18:09:00.002Z</published><updated>2008-04-27T23:09:36.197+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JSquared'/><title type='text'>JSquared 1.0 released</title><content type='html'>Just a quick note to point you to &lt;a href="http://code.google.com/p/jsquared/"&gt;JSquared 1.0&lt;/a&gt; which is now in release.  Please feel free to feedback on your thoughts.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8421903615286376978-2398466842745424512?l=nortools.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nortools.blogspot.com/feeds/2398466842745424512/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8421903615286376978&amp;postID=2398466842745424512' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/2398466842745424512'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/2398466842745424512'/><link rel='alternate' type='text/html' href='http://nortools.blogspot.com/2008/03/jsquared-10-released.html' title='JSquared 1.0 released'/><author><name>James Norton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8421903615286376978.post-1732476105569215029</id><published>2008-02-18T14:12:00.005Z</published><updated>2008-04-27T23:09:29.277+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='JSquared'/><title type='text'>JSquared auto filter list</title><content type='html'>One of the updated objects released with &lt;a href="http://nortools.blogspot.com/2008/02/jsquared-10-beta-2.html"&gt;JSquared 1.0 beta 2&lt;/a&gt; is the auto filter object.  This is a powerful object for filtering lists and is proving useful in a variety of circumstances, not least the creation of auto complete drop down lists for instance for searching.&lt;br /&gt;&lt;br /&gt;At present the object only handles static lists, but by the time JSquared 1.0 is in final release, it will support live lists and a host of further options.  That is to say that you would be able to provide a JSquared ADIJ or JSquared AJAX object as the list of values and the auto filter object will use that object to retrieve the list of values each time it needs to perform a filter.&lt;br /&gt;&lt;br /&gt;The object is designed to work with a text input field and to respond to key presses to perform a filter.  Within this structure, it is quite configurable.  Lets have a look into the object and how to use it.&lt;br /&gt;&lt;br /&gt;To initiate the object, create an instance using the "new" keyword.  The constructor of the object takes 3 parameters, the third of which is optional:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;field - a reference to the DOM node which the auto filter object will respond to and work with&lt;/li&gt;&lt;li&gt;data - the list of items to filter as an Array&lt;/li&gt;&lt;li&gt;options - some options for how the object should perform&lt;/li&gt;&lt;/ol&gt;&lt;span style="font-weight: bold;"&gt;The options&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;objectMember - the array of data to filter can be an array of objects.  If it is, the auto filter object needs to know which member on each object in the array contains the filter data.  This option defines that.&lt;/li&gt;&lt;li&gt;minLength - the minimum number of characters to be entered into the text field before filtering starts.  Defaults to 1.&lt;/li&gt;&lt;li&gt;hoverCssClass - the css class to add to the node which is hovered over (or selected) by the user once the filtered list is displayed&lt;/li&gt;&lt;li&gt;matchAnyCharacter - a boolean value which if true will match the characters entered into the text field against any character in the data list.  If false (the default) it only matches from the start of the items in the data list&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Events&lt;/span&gt;&lt;br /&gt;In addition to these options, you can respond to various events.  Pass in event handlers with the options as follows&lt;br /&gt;&lt;ul&gt;&lt;li&gt;onItemBound - fired when a matching item in the data list is found and bound to the document&lt;/li&gt;&lt;li&gt;onItemSelect - fired when the user selects an item from the filtered list&lt;/li&gt;&lt;li&gt;onFilteredListDraw - fired after the filtered list of items is added to the DOM tree&lt;/li&gt;&lt;/ul&gt;The first 2 events defined above run in the scope of the DOM node representing the relevant filtered list item.  They both will get passed a parameter containing the original data for that list item.  If the original data list was an array of objects, the whole object will get passed.&lt;br /&gt;&lt;br /&gt;The third event defined above runs in the scope of the list of items.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;The HTML&lt;/span&gt;&lt;br /&gt;When the user enters a value into the field which is to support the filtered list, a list of matching items is added to the DOM immediately after the field.  Assuming the value in the field is "value", this list will by default appear as follows:&lt;br /&gt;&lt;br /&gt;&lt;div    style="padding: 10px; background: rgb(234, 234, 196) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;font-family:Courier;font-size:10pt;color:black;"&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;ul&lt;/span&gt; &lt;span style="color:red;"&gt;class&lt;/span&gt;&lt;span style="color:blue;"&gt;="autoCompleteList"&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;    &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;li&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;strong&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;value&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;strong&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt; 1&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;li&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;    &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;li&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;strong&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;value&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;strong&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt; 2&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;li&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;    &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;li&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;strong&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;value&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;strong&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt; 3&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;li&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;ul&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;This HTML can be styled by CSS.  The css class defined for the currently hovered over item (or "hover" by default) is added to the appropriate list item.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Selecting an Item&lt;/span&gt;&lt;br /&gt;When the user selects an item either by clicking on the item in the displayed filtered list or by using the keyboard (up and down cursor keys to choose an item and enter to select it), the value of that item is written into the field.&lt;br /&gt;&lt;br /&gt;That is pretty much all there is to it.  Its quite simple really!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8421903615286376978-1732476105569215029?l=nortools.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nortools.blogspot.com/feeds/1732476105569215029/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8421903615286376978&amp;postID=1732476105569215029' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/1732476105569215029'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/1732476105569215029'/><link rel='alternate' type='text/html' href='http://nortools.blogspot.com/2008/02/jsquared-auto-filter-list.html' title='JSquared auto filter list'/><author><name>James Norton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8421903615286376978.post-4209539688052481561</id><published>2008-02-18T14:09:00.002Z</published><updated>2008-04-27T23:09:18.778+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JSquared'/><title type='text'>JSquared Packages</title><content type='html'>With the &lt;a href="http://nortools.blogspot.com/2008/02/jsquared-10-beta-2.html"&gt;release of JSquared beta 2&lt;/a&gt;, I have provided one file containing the full library which is also minified.  This file weighs in at 29Kb!  I would always recommend using JSquared in its componentized format, just including what you need at any time.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8421903615286376978-4209539688052481561?l=nortools.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nortools.blogspot.com/feeds/4209539688052481561/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8421903615286376978&amp;postID=4209539688052481561' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/4209539688052481561'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/4209539688052481561'/><link rel='alternate' type='text/html' href='http://nortools.blogspot.com/2008/02/jsquared-packages.html' title='JSquared Packages'/><author><name>James Norton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8421903615286376978.post-2183446591755029140</id><published>2008-02-18T14:02:00.003Z</published><updated>2008-04-27T23:08:51.546+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JSquared'/><title type='text'>JSquared 1.0 Beta 2</title><content type='html'>JSquared 1.0 Beta 2 has just gone live and is available for &lt;a href="http://code.google.com/p/jsquared/"&gt;download now&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;This version has a number of enhancements over beta 1, not least the deployment method!  You can now upgrade from beta 1 to beta 2 by just replacing the old code with the new.  I have also provided full versions of the library with all its components in one file in both compressed and uncompressed formats.&lt;br /&gt;&lt;br /&gt;There have been a number of improvements and additions since beta 1:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Better DOMReady handling&lt;/li&gt;&lt;li&gt;Much faster "trim" method on strings&lt;/li&gt;&lt;li&gt;New image rollover object - back to the future!&lt;/li&gt;&lt;li&gt;Delegate handling pattern&lt;/li&gt;&lt;li&gt;New auto filtering object.  Highly configurable.&lt;/li&gt;&lt;li&gt;A URL manager object for adding entries to the browser history and allowing bookmarking in an AJAX application&lt;/li&gt;&lt;li&gt;Loads of little bug fixes&lt;/li&gt;&lt;/ul&gt;For those who still want it, beta 1 is still available for download as well.&lt;br /&gt;&lt;br /&gt;Keep an eye on this blog for more information about all the JSquared features.  You should already know about &lt;a href="http://nortools.blogspot.com/2008/01/asynchronous-javascript-part-3-using.html"&gt;ADIJ&lt;/a&gt;!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8421903615286376978-2183446591755029140?l=nortools.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nortools.blogspot.com/feeds/2183446591755029140/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8421903615286376978&amp;postID=2183446591755029140' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/2183446591755029140'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/2183446591755029140'/><link rel='alternate' type='text/html' href='http://nortools.blogspot.com/2008/02/jsquared-10-beta-2.html' title='JSquared 1.0 Beta 2'/><author><name>James Norton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8421903615286376978.post-1634764331899126420</id><published>2008-02-12T14:23:00.000Z</published><updated>2008-02-12T14:26:39.190Z</updated><title type='text'>Lack of posts</title><content type='html'>Apologies to all those avid readers out there for the recent lack of posts on this blog. &lt;br /&gt;&lt;br /&gt;This is what happens when you are less than 3 weeks from being married! &lt;br /&gt;&lt;br /&gt;I will attempt to complete my series on Asynchronous JavaScript techniques (only 3 more parts to go) before heading off to Thailand for 2 weeks for our honeymoon.&lt;br /&gt;&lt;br /&gt;Roll on March 2nd...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8421903615286376978-1634764331899126420?l=nortools.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nortools.blogspot.com/feeds/1634764331899126420/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8421903615286376978&amp;postID=1634764331899126420' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/1634764331899126420'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/1634764331899126420'/><link rel='alternate' type='text/html' href='http://nortools.blogspot.com/2008/02/lack-of-posts.html' title='Lack of posts'/><author><name>James Norton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8421903615286376978.post-6776065416638792342</id><published>2008-02-04T16:58:00.002Z</published><updated>2008-04-27T23:08:38.814+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Web standards'/><category scheme='http://www.blogger.com/atom/ns#' term='HTML'/><category scheme='http://www.blogger.com/atom/ns#' term='HTML 5'/><title type='text'>HTML 5 and Web Standards</title><content type='html'>With the recent publishing of the &lt;a href="http://www.w3.org/TR/2008/WD-html5-20080122/"&gt;W3C HTML 5 Working Draft&lt;/a&gt;, and the debacle which is &lt;a href="http://alistapart.com/articles/beyonddoctype"&gt;IE versioning through meta tags&lt;/a&gt;, I have been having some thoughts about web standards.&lt;br /&gt;&lt;br /&gt;It so happens that I am not the only one!  &lt;a href="http://www.molly.com/2008/01/31/web-standards-arent/"&gt;Molly E. Holzschlag has also been thinking&lt;/a&gt;.  Whilst her thoughts are somewhat more drastic than mine, I felt it time to put forward my thoughts on the next generation of HTML on the web.&lt;br /&gt;&lt;br /&gt;HTML 5 is a massive specification introducing many new tags and attributes of which without a doubt my favourite is the &lt;a href="http://www.w3.org/TR/2008/WD-html5-20080122/#the-irrelevant"&gt;irrelevant attribute&lt;/a&gt;.  I would personally be quite happy to wrap large parts of the spec in such a tag!&lt;br /&gt;&lt;br /&gt;I believe strongly in simplification and I do not believe HTML 5 simplifies HTML.  What I think we need is less not more.  There is one very specific point which grates.  HTML should enforce an XML syntax - tags should have to be closed and have to be well formed.  &lt;a href="http://www.w3.org/TR/2008/WD-html5-20080122/#closing"&gt;HTML 5 allows unclosed tags&lt;/a&gt; and this to my mind is a step backwards.  Indeed, I see the spec contains code a bit like this:&lt;br /&gt;&lt;br /&gt;&lt;div    style="padding: 10px; background: rgb(234, 234, 196) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;font-family:Courier;font-size:10pt;color:black;"&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;dl&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;      &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;dt&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;Radius: &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;dd&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;meter&lt;/span&gt; &lt;span style="color:red;"&gt;min&lt;/span&gt;&lt;span style="color:blue;"&gt;=0&lt;/span&gt; &lt;span style="color:red;"&gt;max&lt;/span&gt;&lt;span style="color:blue;"&gt;=20&lt;/span&gt; &lt;span style="color:red;"&gt;value&lt;/span&gt;&lt;span style="color:blue;"&gt;=12&amp;gt;&lt;/span&gt;12cm&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;meter&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;      &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;dt&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;Height: &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;dd&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;meter&lt;/span&gt; &lt;span style="color:red;"&gt;min&lt;/span&gt;&lt;span style="color:blue;"&gt;=0&lt;/span&gt; &lt;span style="color:red;"&gt;max&lt;/span&gt;&lt;span style="color:blue;"&gt;=10&lt;/span&gt; &lt;span style="color:red;"&gt;value&lt;/span&gt;&lt;span style="color:blue;"&gt;=2&amp;gt;&lt;/span&gt;2cm&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;meter&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;dl&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;This is some ugly stuff!&lt;br /&gt;&lt;br /&gt;I believe HTML 5 should actually be XHTML 5 (or version 2 or whatever version you like!).  It should contain a small set of semantic tags including paragraph, emphasis, lists, audio, video, anchors, images, divisions (or sections) amongst others, creating a small set of recognised tags with well defined default rendering for each.  As an author, I should be allowed to create ANY OTHER TAG I LIKE as long as it is well formed XML.  The default rendering for each unrecognised tag should be as an inline element and they should offer no semantic meaning.&lt;br /&gt;&lt;br /&gt;The tags I "create" should be able to be styled through CSS and accessible as DOM nodes via JavaScript.&lt;br /&gt;&lt;br /&gt;Its simple.  Or is it too simple?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8421903615286376978-6776065416638792342?l=nortools.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nortools.blogspot.com/feeds/6776065416638792342/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8421903615286376978&amp;postID=6776065416638792342' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/6776065416638792342'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/6776065416638792342'/><link rel='alternate' type='text/html' href='http://nortools.blogspot.com/2008/02/html-5-and-web-standards.html' title='HTML 5 and Web Standards'/><author><name>James Norton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8421903615286376978.post-7987240147776582151</id><published>2008-01-25T13:47:00.001Z</published><updated>2008-04-27T23:08:21.490+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Internet Explorer'/><title type='text'>IE8 - Version Switching</title><content type='html'>There has been much talk over the past few days about IE8 and its new concept of version &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_0"&gt;targeting&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;There is a &lt;a href="http://www.robertnyman.com/2008/01/23/version-targeting-in-ie-8-and-an-alternative-path-for-microsoft/"&gt;lovely post by &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;Robert&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;Nyman&lt;/span&gt;&lt;/a&gt; where he considers an alternative.  I agree with much of what he says.&lt;br /&gt;&lt;br /&gt;My feelings on this matter do differ in some ways.  I have a strong conviction that IE8 should render things as well as it can all the time.  I wont object to the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;doctype&lt;/span&gt; switch - it has been around too long now - but there should be strong discouragement of its use.&lt;br /&gt;&lt;br /&gt;I am well aware that for some the web will be "broken".  But surely this is OK.  It seems that browser vendors and especially Microsoft are helping those amateurs who think they can do web interface development.  I have no problem with people building their own websites at all, but it is time to realise that writing good &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;XHTML&lt;/span&gt; and &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;CSS&lt;/span&gt; is not easy.  Its time to put things right, have some short term pain but get that long term gain.&lt;br /&gt;&lt;br /&gt;This combined with Robert's approach of standalone versions could make the world a better place.  Tools for building websites "properly" will appear in time.&lt;br /&gt;&lt;br /&gt;Just remember, &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;XHTML&lt;/span&gt; and &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;CSS&lt;/span&gt; are hard to do well, we want to encourage amateurs to have websites - everyone should be able to have a website - but its not easy.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8421903615286376978-7987240147776582151?l=nortools.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nortools.blogspot.com/feeds/7987240147776582151/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8421903615286376978&amp;postID=7987240147776582151' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/7987240147776582151'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/7987240147776582151'/><link rel='alternate' type='text/html' href='http://nortools.blogspot.com/2008/01/ie8-version-switching.html' title='IE8 - Version Switching'/><author><name>James Norton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8421903615286376978.post-4022827141108706386</id><published>2008-01-25T10:32:00.001Z</published><updated>2008-04-27T23:04:13.303+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='ADIJ'/><title type='text'>Asynchronous JavaScript Part 3 - Using ADIJ</title><content type='html'>In &lt;a href="http://nortools.blogspot.com/2008/01/asynchronous-javascript-part-1-adij.html"&gt;part 1&lt;/a&gt; and &lt;a href="http://nortools.blogspot.com/2008/01/asynchronous-javascript-part-2-adij.html"&gt;part 2&lt;/a&gt; of this series on asynchronous JavaScript techniques, I have introduced the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;ADIJ&lt;/span&gt; object.  Now, I will &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_1"&gt;demonstrate&lt;/span&gt; just how easy it is to use the object with an extremely simple code example.&lt;br /&gt;&lt;br /&gt;&lt;div    style="padding: 10px; background: rgb(234, 234, 196) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;font-family:Courier;font-size:10pt;color:black;"&gt;&lt;span style="color:blue;"&gt;var&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;myAdij&lt;/span&gt; = &lt;span style="color:blue;"&gt;new&lt;/span&gt; J2.&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;ADIJ&lt;/span&gt;( {&lt;br /&gt;&lt;p style="margin: 0px;"&gt;    URL: &lt;span style="color: rgb(163, 21, 21);"&gt;"/&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;getADIJdata&lt;/span&gt;.&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;json&lt;/span&gt;"&lt;/span&gt;,&lt;/p&gt;    &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;onSuccess&lt;/span&gt;: &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;successHandler&lt;/span&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;} );&lt;/p&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;myAdij&lt;/span&gt;.send();&lt;br /&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color:blue;"&gt;function&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;successHandler&lt;/span&gt;(&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;myAdij&lt;/span&gt;) {&lt;/p&gt;    &lt;span style="color:blue;"&gt;var&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_11"&gt;jsonData&lt;/span&gt; = &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_12"&gt;myAdij&lt;/span&gt;.&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_13"&gt;getResponseText&lt;/span&gt;();&lt;br /&gt;&lt;p style="margin: 0px;"&gt;    ....&lt;/p&gt;}&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;In this example, I create a variable called &lt;span style="font-style: italic;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_14"&gt;myAdij&lt;/span&gt;&lt;/span&gt; which is set to a new instance of the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_15"&gt;ADIJ&lt;/span&gt; object.  I pass an object literal of values into the constructor of the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_16"&gt;ADIJ&lt;/span&gt; object containing the URL which I wish to request and the success handler which will get called when the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_17"&gt;ADIJ&lt;/span&gt; object gets a response to this request.&lt;br /&gt;&lt;br /&gt;I then call the &lt;span style="font-style: italic;"&gt;send&lt;/span&gt; method which will send the request.&lt;br /&gt;&lt;br /&gt;When the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_18"&gt;ADIJ&lt;/span&gt; object gets its response, &lt;span style="font-style: italic;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_19"&gt;successHandler&lt;/span&gt;&lt;/span&gt; will be called.  It will be passed one argument which is a different form of the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_20"&gt;ADIJ&lt;/span&gt; object now containing a method &lt;span style="font-style: italic;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_21"&gt;getResponseText&lt;/span&gt;&lt;/span&gt; which will return the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_22"&gt;JSON&lt;/span&gt; object sent as the response to the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_23"&gt;ADIJ&lt;/span&gt; request.&lt;br /&gt;&lt;br /&gt;Once &lt;span style="font-style: italic;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_24"&gt;successHandler&lt;/span&gt;&lt;/span&gt; had finished being executed, the original &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_25"&gt;ADIJ&lt;/span&gt; object can be garbage collected by the browser assuming there are no other live references to it.&lt;br /&gt;&lt;br /&gt;It is also possible to create and send the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_26"&gt;ADIJ&lt;/span&gt; request in one line of code and without assigning it to a variable.  This can be useful in instances when the original &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_27"&gt;ADIJ&lt;/span&gt; object will not be needed again.&lt;br /&gt;&lt;br /&gt;&lt;div    style="padding: 10px; background: rgb(234, 234, 196) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;font-family:Courier;font-size:10pt;color:black;"&gt;&lt;span style="color:blue;"&gt;new&lt;/span&gt; J2.&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_28"&gt;ADIJ&lt;/span&gt;( {&lt;br /&gt;&lt;p style="margin: 0px;"&gt;    URL: &lt;span style="color: rgb(163, 21, 21);"&gt;"/&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_29"&gt;getADIJdata&lt;/span&gt;.&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_30"&gt;json&lt;/span&gt;"&lt;/span&gt;,&lt;/p&gt;&lt;p style="margin: 0px;"&gt;    &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_31"&gt;onSuccess&lt;/span&gt;: &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_32"&gt;successHandler&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;} ).send();&lt;/p&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color:blue;"&gt;function&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_33"&gt;successHandler&lt;/span&gt;(&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_34"&gt;myAdij&lt;/span&gt;) {&lt;/p&gt;&lt;p style="margin: 0px;"&gt;    &lt;span style="color:blue;"&gt;var&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_35"&gt;jsonData&lt;/span&gt; = &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_36"&gt;myAdij&lt;/span&gt;.&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_37"&gt;getResponseText&lt;/span&gt;();&lt;/p&gt;&lt;p style="margin: 0px;"&gt;    ....&lt;/p&gt;&lt;p style="margin: 0px;"&gt;}&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;Note that the send method is now called &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_38"&gt;in line&lt;/span&gt; with the construction of the new &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_39"&gt;ADIJ&lt;/span&gt; object.&lt;br /&gt;&lt;br /&gt;It is as simple and easy as that!  So go, play and enjoy and when this series returns, we will be discussing AJAX and particularly &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_40"&gt;JSquared&lt;/span&gt; AJAX.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8421903615286376978-4022827141108706386?l=nortools.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nortools.blogspot.com/feeds/4022827141108706386/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8421903615286376978&amp;postID=4022827141108706386' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/4022827141108706386'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/4022827141108706386'/><link rel='alternate' type='text/html' href='http://nortools.blogspot.com/2008/01/asynchronous-javascript-part-3-using.html' title='Asynchronous JavaScript Part 3 - Using ADIJ'/><author><name>James Norton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8421903615286376978.post-1672683578207607022</id><published>2008-01-18T09:52:00.001Z</published><updated>2008-04-27T23:04:00.060+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='CSS reset'/><category scheme='http://www.blogger.com/atom/ns#' term='CSS'/><title type='text'>Structured CSS</title><content type='html'>One of the most challenging aspects of starting a new project is deciding how to structure the CSS.  Often, not all the designs are complete, and sometimes very few are done and things are not signed off etc.  Therefore it is always important to have a structure which allows for quick and easy changes and even the retrospective coding of a style guide into the CSS.&lt;br /&gt;&lt;br /&gt;I am personally not a fan of CSS resets such as &lt;a href="http://meyerweb.com/eric/thoughts/2008/01/15/resetting-again/"&gt;Eric Meyer's&lt;/a&gt;  but I do like to have flexibility and structure in my work.&lt;br /&gt;&lt;br /&gt;Whilst I get some arguments from colleagues about my approach, those who work on projects with me have so far not had cause for complaint and have commented that my approach seems to work.  The crux of it is that I like to do the majority of the CSS work up-front and do as little as possible as more and more pages are added into the site.&lt;br /&gt;&lt;br /&gt;I still subscribe to the global reset:&lt;br /&gt;&lt;br /&gt;&lt;div    style="padding: 10px; background: rgb(234, 234, 196) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;font-family:Courier;font-size:10pt;color:black;"&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;*&lt;/span&gt; {&lt;br /&gt;&lt;p style="margin: 0px;"&gt;    &lt;span style="color:red;"&gt;margin&lt;/span&gt;: &lt;span style="color:blue;"&gt;0&lt;/span&gt;;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;    &lt;span style="color:red;"&gt;padding&lt;/span&gt;: &lt;span style="color:blue;"&gt;0&lt;/span&gt;;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;}&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;I then like to set all the defaults from scratch on the core elements: headers, tables, anchors, paragraphs, lists etc.&lt;br /&gt;&lt;br /&gt;My other practice which causes discussion is my file structure.  There are different ways of organising &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;CSS&lt;/span&gt; files and some people like to take the one file approach where everything is put into one massive file.  I cannot abide this approach - how can you find anything!?  The answer is often that good commenting helps, but I don't think developers are very good at commenting well!&lt;br /&gt;&lt;br /&gt;My other issue with the single &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;CSS&lt;/span&gt; file is that for every page the user has to download every line of &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;CSS&lt;/span&gt; and in a rich website, there can be a lot!&lt;br /&gt;&lt;br /&gt;I prefer to separate the basic &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;CSS&lt;/span&gt; into the following files:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;global.&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;css&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;All global styles including my mini-reset as above, basic styles for the common tags (lists, tables etc).  Styling for global site elements.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;typography.&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;css&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Basic typography styles - paragraphs, headers and text colouring for different elements.  Anchor styles as well including hover styles etc.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;forms.&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;css&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Basic form styling.  I always insist upon forms looking very similar across the website so I can style them once.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;navigation.&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_11"&gt;css&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;All global navigation styles typically including primary and secondary navigation (tertiary if it is applicable), footer styles, any in page tabbed navigation etc&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_12"&gt;ie&lt;/span&gt;.&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_13"&gt;css&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Included for all IE versions 7 and lower through conditional comments.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_14"&gt;ie&lt;/span&gt;6.&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_15"&gt;css&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Included for all IE versions 6 and lower through conditional comments.&lt;br /&gt;&lt;br /&gt;Each of the above files would be included on every page of the website.  I would then create further style sheets by section or template or functional usage depending on the website.  I would normally not create a style sheet per page or per module, but I do normally create additional special style sheets for the website home page and for search results if it is different enough.&lt;br /&gt;&lt;br /&gt;Within my style sheets I try and implement rules such that each section of &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_16"&gt;CSS&lt;/span&gt; is commented &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_17"&gt;eg&lt;/span&gt;:&lt;br /&gt;&lt;br /&gt;&lt;div    style="padding: 10px; background: rgb(234, 234, 196) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;font-family:Courier;font-size:10pt;color:black;"&gt;&lt;span style="color:green;"&gt;/* Inbox styles */&lt;/span&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;table#Inbox&lt;/span&gt; {&lt;/p&gt;&lt;p style="margin: 0px;"&gt;    ....&lt;/p&gt;&lt;p style="margin: 0px;"&gt;}&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;....&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;I like to have the styles in a sensible order which is normally the same as the markup order.  So styling for elements which are children of or appear after the &lt;span style="font-style: italic;"&gt;table&lt;/span&gt; with ID &lt;span style="font-style: italic;"&gt;Inbox&lt;/span&gt; would appear later in the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_18"&gt;CSS&lt;/span&gt; file.&lt;br /&gt;&lt;br /&gt;And that's it.  No magic, nothing too special, just a structure borne out of experience and specifically the experiencing of managing badly written &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_19"&gt;CSS&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_20"&gt;CSS&lt;/span&gt; is not easy, but a good approach can at least make it simple.&lt;br /&gt;&lt;br /&gt;One special note - consistency of approach to &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_21"&gt;CSS&lt;/span&gt; on a project is absolutely key until some decent development tools come along.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8421903615286376978-1672683578207607022?l=nortools.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nortools.blogspot.com/feeds/1672683578207607022/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8421903615286376978&amp;postID=1672683578207607022' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/1672683578207607022'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/1672683578207607022'/><link rel='alternate' type='text/html' href='http://nortools.blogspot.com/2008/01/structured-css.html' title='Structured CSS'/><author><name>James Norton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8421903615286376978.post-8174589097124541712</id><published>2008-01-09T17:26:00.001Z</published><updated>2008-04-27T23:03:01.266+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='ADIJ'/><title type='text'>Asynchronous JavaScript Part 2 - The ADIJ Object</title><content type='html'>In a &lt;a href="http://nortools.blogspot.com/2008/01/asynchronous-javascript-part-1-adij.html"&gt;previous post&lt;/a&gt;, I discussed what ADIJ is.&lt;br /&gt;&lt;br /&gt;ADIJ is now open source and you can &lt;a href="http://code.google.com/p/jsquared/"&gt;get ADIJ here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;This is part 2 of my series on asynchronous JavaScript and today I will focus on how the ADIJ object itself works.  In part 3 of this series, I will discuss how to use the object.  Later in the series, I will introduce my AJAX object which is also open source and available along with ADIJ.  These 2 objects share a simple interface and so can be interchanged fairly easily.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;How does ADIJ work?&lt;/span&gt;&lt;br /&gt;Whilst answering this question, we must bear in mind that ADIJ is an asynchronous tool which ultimately will make an HTTP request and indirectly handle the response of that request.  JavaScript is simply the intermediate layer which processes the HTTP response and passes that response back to the ADIJ object.&lt;br /&gt;&lt;br /&gt;ADIJ is an instance based tool.  You create instances of the ADIJ object and apply properties to that instance.  Each ADIJ instance is given a unique ID which is used to identify each ADIJ object.  This is most useful when handling responses.&lt;br /&gt;&lt;br /&gt;The following properties can be applied to each ADIJ instance (and ultimately each request made):&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;URL&lt;/span&gt; - this is the URL which ADIJ will use for the &lt;span style="font-style: italic;"&gt;src&lt;/span&gt; attribute of the script tag which will be injected into the document when the ADIJ request is sent.  The response from this URL has to be JavaScript formed to work with ADIJ.&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;onSuccess&lt;/span&gt; - this is the function which will handle the response.  It is similar to the handler for &lt;span style="font-style: italic;"&gt;onReadyStateChange&lt;/span&gt; in an AJAX request.&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;scope&lt;/span&gt; (optional) - this defines the scope that the onSuccess handler will run within.  &lt;a href="http://www.digital-web.com/articles/scope_in_javascript/"&gt;Scope&lt;/a&gt; is a larger JavaScript topic which cannot be covered within this post.  Suffice to say that if this optional property is supplied, it should be an object and defines the value of the &lt;span style="font-style: italic;"&gt;this&lt;/span&gt; keyword in the onSuccess handler function.&lt;/li&gt;&lt;/ul&gt;Once you are ready to send your ADIJ request, call the &lt;span style="font-style: italic;"&gt;send&lt;/span&gt; method.  The ADIJ object will write out a script tag into the document which will look something like this:&lt;br /&gt;&lt;br /&gt;&lt;div    style="padding: 10px; background: rgb(234, 234, 196) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;font-family:Courier;font-size:10pt;color:black;"&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;script&lt;/span&gt; &lt;span style="color:red;"&gt;type&lt;/span&gt;&lt;span style="color:blue;"&gt;="text/javascript"&lt;/span&gt; &lt;span style="color:red;"&gt;src&lt;/span&gt;&lt;span style="color:blue;"&gt;="MyADIJUrl.js?rid=ADIJ_1&amp;amp;uqid=1199900579224"&amp;gt;&lt;/span&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;script&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;ADIJ will add 2 items to the querystring of the request:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;rid&lt;/span&gt; - this is the ADIJ request ID which the server will need to be aware of&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;uqid&lt;/span&gt; - this is a date and time stamp of when the request was sent.  This is used to stop ADIJ requests being cached.&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;How does ADIJ process the response?&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;When the server gets an ADIJ request, it needs to respond with JavaScript.  It is very important that the interface developer works closely with an application developer to ensure the server side of the application is setup to handle ADIJ correctly.&lt;br /&gt;&lt;br /&gt;The final response to the onSuccess handler defined on the ADIJ object will be &lt;a href="http://www.json.org/"&gt;JSON&lt;/a&gt;, but the response from the server will be a function call which will look something like:&lt;br /&gt;&lt;br /&gt;&lt;div style="padding: 10px; background: rgb(234, 234, 196) none repeat scroll 0% 50%; font-family: Courier; font-size: 10pt; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;&lt;p style="margin: 0px;"&gt;Tools.ADIJ.prototype.handleResponse( id, json );&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Tools.ADIJ&lt;/span&gt; is the ADIJ object itself.&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Tools.ADIJ.prototype.handleResponse&lt;/span&gt; is a function on the prototype of Tools.ADIJ&lt;br /&gt;&lt;span style="font-style: italic;"&gt;id&lt;/span&gt; is the ID of the ADIJ request as passed to the server in the querystring of the request.  This ID is auto-generated by the ADIJ object and automatically appended to the specified URL for the ADIJ request&lt;br /&gt;&lt;span style="font-style: italic;"&gt;json&lt;/span&gt; is the JSON object to pass back to the onSuccess handler defined in the instance of the ADIJ object given the ID &lt;span style="font-style: italic;"&gt;id&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;By this method, multiple ADIJ requests can be sent from and handled by the client side code with ease.&lt;br /&gt;&lt;br /&gt;In part 3 of this series, I will show just how simple it is to write the JavaScript code to use ADIJ.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8421903615286376978-8174589097124541712?l=nortools.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nortools.blogspot.com/feeds/8174589097124541712/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8421903615286376978&amp;postID=8174589097124541712' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/8174589097124541712'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/8174589097124541712'/><link rel='alternate' type='text/html' href='http://nortools.blogspot.com/2008/01/asynchronous-javascript-part-2-adij.html' title='Asynchronous JavaScript Part 2 - The ADIJ Object'/><author><name>James Norton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8421903615286376978.post-2324582744131665740</id><published>2008-01-08T13:48:00.002Z</published><updated>2008-12-11T23:22:14.630Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='JSquared'/><title type='text'>No $</title><content type='html'>Over the past few months, I have been developing and testing my own JavaScript library.  I am delighted to announce that &lt;a href="http://code.google.com/p/jsquared/"&gt;JSquared&lt;/a&gt; is now open source software and available at &lt;a href="http://code.google.com/p/jsquared/"&gt;Google Code&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I will be blogging about the features of the library over the coming few months.  The library includes some asynchronous JavaScript tools and you can &lt;a href="http://nortools.blogspot.com/2008/01/asynchronous-javascript-part-1-adij.html"&gt;read part 1&lt;/a&gt; of my series on asynchronous JavaScript.&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_MYZ44Y8H5KI/R4OCLnoxeVI/AAAAAAAAAAc/iAXdwDsFoyw/s1600-h/jsquared.png"&gt;&lt;br /&gt;&lt;/a&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_MYZ44Y8H5KI/R4OC8noxeXI/AAAAAAAAAAs/ZjmrWrqXLn0/s1600-h/jsquared.png"&gt;&lt;br /&gt;&lt;/a&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_MYZ44Y8H5KI/R4ODhHoxeYI/AAAAAAAAAA0/YDC-0x40cEA/s1600-h/jsquared.png"&gt;&lt;img style="cursor: pointer;" src="http://3.bp.blogspot.com/_MYZ44Y8H5KI/R4ODhHoxeYI/AAAAAAAAAA0/YDC-0x40cEA/s320/jsquared.png" alt="" id="BLOGGER_PHOTO_ID_5153107003650963842" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8421903615286376978-2324582744131665740?l=nortools.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nortools.blogspot.com/feeds/2324582744131665740/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8421903615286376978&amp;postID=2324582744131665740' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/2324582744131665740'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/2324582744131665740'/><link rel='alternate' type='text/html' href='http://nortools.blogspot.com/2008/01/no.html' title='No $'/><author><name>James Norton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_MYZ44Y8H5KI/R4ODhHoxeYI/AAAAAAAAAA0/YDC-0x40cEA/s72-c/jsquared.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8421903615286376978.post-2411959024763869556</id><published>2008-01-07T16:01:00.004Z</published><updated>2008-04-27T23:07:13.435+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Progressive enhancement'/><category scheme='http://www.blogger.com/atom/ns#' term='CSS'/><title type='text'>Is CSS the ultimate expression of progressive enhancement?</title><content type='html'>Following up on my previous post about &lt;a href="http://nortools.blogspot.com/2007/12/progressive-enhancement.html"&gt;progressive enhancement&lt;/a&gt;, I wish to pose the question:&lt;br /&gt;Is CSS the ultimate expression of progressive enhancement?&lt;br /&gt;&lt;br /&gt;To help us address the question, lets briefly remind ourselves that progressive enhancement is a technique whereby the way a web page operates is enhanced if the user agent being used supports certain features but if the user agent does not, then nothing is lost.  The user can still see all content and use all features of the &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_2"&gt;web page&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;So, does this hold true of &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;CSS&lt;/span&gt;?  Well, given valid markup, I believe it does and I certainly believe it should.&lt;br /&gt;&lt;br /&gt;That does not answer the question posed though.  I am firmly of the opinion that the answer is &lt;span style="font-weight: bold;"&gt;yes&lt;/span&gt;.  &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;CSS&lt;/span&gt; is so powerful and so able to change the way a &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_5"&gt;web page&lt;/span&gt; looks but without itself forming any part of the content or functionality of that &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_6"&gt;web page&lt;/span&gt;, that I believe it must be the ultimate expression of progressive enhancement.&lt;br /&gt;&lt;br /&gt;Do you agree?  Do you disagree?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8421903615286376978-2411959024763869556?l=nortools.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nortools.blogspot.com/feeds/2411959024763869556/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8421903615286376978&amp;postID=2411959024763869556' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/2411959024763869556'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/2411959024763869556'/><link rel='alternate' type='text/html' href='http://nortools.blogspot.com/2008/01/is-css-ultimate-expression-of.html' title='Is CSS the ultimate expression of progressive enhancement?'/><author><name>James Norton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8421903615286376978.post-1411015727789496014</id><published>2008-01-03T11:46:00.001Z</published><updated>2008-04-25T16:24:58.443+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='ADIJ'/><title type='text'>Asynchronous JavaScript Part 1 - ADIJ</title><content type='html'>This is the first in a series of posts regarding asynchronous JavaScript techniques and tools.&lt;br /&gt;&lt;br /&gt;In this edition, I will introduce ADIJ.  I will ultimately provide code and examples for each of the tools I recommend using.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;The What&lt;/span&gt;&lt;br /&gt;Asynchronous DOM Injected &lt;a href="http://www.json.org/"&gt;JSON&lt;/a&gt; or ADIJ is what I have termed a fairly common technique found today for getting data from a server using JavaScript in an asynchronous fashion.  This technique is more commonly known as &lt;a href="http://www.mindsack.com/uxe/dynodes/"&gt;the script tag hack&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;The How&lt;/span&gt;&lt;br /&gt;Its a very simple technique which involves simply adding a script tag with a valid &lt;span style="font-style: italic;"&gt;src&lt;/span&gt; attribute to the DOM tree.  When the script tag is added to the document, the browser will make a request to the URL specified in the src, and load the returned content which will be interpreted and executed immediately.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;The Why&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;I have found ADIJ most useful thus far in mapping mashups.  The data returned will normally be in JSON format and this is efficient for parsing and adding points to a map.  But the technique can work very well for any public data which needs to be delivered asynchronously to the browser.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Any issues?&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Any data returned using ADIJ can be intercepted and in theory, scripts can be injected into your page.  However, I normally ensure that I only accept valid JSON containing Objects and Strings.  I would never execute a function returned by this technique.  This is not a major issue, but one to be aware of.   Only ever use ADIJ for fully public data, never for secure data.  Be aware that all cookies are provided when the request is made.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Why ADIJ?&lt;/span&gt;&lt;br /&gt;ADIJ is more than just a silly name for the script tag hack.  ADIJ is a helper object which can allow you to send multiple requests on demand and receive valid JSON data back with co-operation from the server.&lt;br /&gt;&lt;br /&gt;Using ADIJ, you provide a handler function (similar to the callback in AJAX) which will receive the JSON data when the request completes successfully.  The ADIJ object will manage your requests and handle all the responses for you, ultimately passing the response back to your specified handler function.&lt;br /&gt;&lt;br /&gt;The ADIJ object provides a powerful first item in your asynchronous JavaScript toolkit.&lt;br /&gt;&lt;br /&gt;In part 2 of this series I will go through the ADIJ object and provide an example.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8421903615286376978-1411015727789496014?l=nortools.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nortools.blogspot.com/feeds/1411015727789496014/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8421903615286376978&amp;postID=1411015727789496014' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/1411015727789496014'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/1411015727789496014'/><link rel='alternate' type='text/html' href='http://nortools.blogspot.com/2008/01/asynchronous-javascript-part-1-adij.html' title='Asynchronous JavaScript Part 1 - ADIJ'/><author><name>James Norton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8421903615286376978.post-1787983908586260102</id><published>2007-12-18T17:50:00.001Z</published><updated>2008-04-27T22:59:21.683+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Browser support'/><category scheme='http://www.blogger.com/atom/ns#' term='Browsers'/><title type='text'>Browser support</title><content type='html'>This is an issue which crops up in one form or another on almost every project I have ever worked on.  Its normally the project manager who will approach me and say in a sometimes off-handed way something like &lt;span style="font-style: italic;"&gt;"I assume we will support this list of browsers (which someone gave me back in 2001)."&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;My usual answer is &lt;span style="font-style: italic;"&gt;"No.  We will support this standard support matrix."&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I then proceed to hand the project manager something which at the time of writing includes the following:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Internet Explorer 6+&lt;/li&gt;&lt;li&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;Firefox&lt;/span&gt; 1.5+ (all platforms)&lt;/li&gt;&lt;li&gt;Safari 2+ (all platforms)&lt;/li&gt;&lt;li&gt;Opera 9+ (all platforms)&lt;/li&gt;&lt;/ul&gt;This is all well and good, but the real purpose of this kind of browser support matrix is actually to fulfill some sort of contractual requirements with a client and to appease the project manager.&lt;br /&gt;&lt;br /&gt;I also consider this matrix to be a testing guide for the testers of the website.   Most testers are not completely familiar with ID concepts, and they need some help.  I have seen testers using up to 20 different browsers and raising bugs if they are not all perfect.  This is obviously very costly on the project - testing takes a long time and fixing the bugs is extremely tedious and often not really possible.&lt;br /&gt;&lt;br /&gt;To get around this issues (and to help with dealing with the client who still happens to be using &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;Ie&lt;/span&gt;5 on Windows 98) I normally talk in terms of graded support.  At the time of writing, I use 2 level of support:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Level 1&lt;/span&gt;&lt;br /&gt;All features of the website are fully functional.  All content is available.  The &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_2"&gt;web pages&lt;/span&gt; will match the designs provided completely.  The &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_3"&gt;web pages&lt;/span&gt; will look the same across all browsers at this level.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Level 2&lt;/span&gt;&lt;br /&gt;All features of the website are &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_4"&gt;functional&lt;/span&gt; if only in a fall back manner.  All content is available.  The &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_5"&gt;web pages&lt;/span&gt; will largely match provided designs.  The &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_6"&gt;web pages&lt;/span&gt; may look slightly different between browsers at this level and those at other levels.&lt;br /&gt;&lt;br /&gt;This provides a sensible testing structure as well as fulfilling all other requirements.  If an awkward browser (such as IE 5.5) absolutely must be supported, we have the option of only offering level 2 support - the key here is that all content will be available.&lt;br /&gt;&lt;br /&gt;In reality, browser support only matters for the visual and enhanced behavior of the website.  If the website is built using the principles of &lt;a href="http://nortools.blogspot.com/2007/12/progressive-enhancement.html"&gt;progressive enhancement&lt;/a&gt;, then all user agents, all browsers should be able to access the website in some form or another.  It is the content of the website which is most important, and using well structured, semantic HTML should ensure that this content is available to all.&lt;br /&gt;&lt;br /&gt;The message here is that agreeing a sensible browser support matrix is very important in both a business sense and for testing.  It is also imperative to adhere to the agreed support levels, but the principles of &lt;a href="http://nortools.blogspot.com/2007/12/progressive-enhancement.html"&gt;progressive enhancement&lt;/a&gt;, particularly starting with well formed, semantic HTML will ensure the widest possible support even if that is with a degraded experience.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8421903615286376978-1787983908586260102?l=nortools.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nortools.blogspot.com/feeds/1787983908586260102/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8421903615286376978&amp;postID=1787983908586260102' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/1787983908586260102'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/1787983908586260102'/><link rel='alternate' type='text/html' href='http://nortools.blogspot.com/2007/12/browser-support.html' title='Browser support'/><author><name>James Norton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8421903615286376978.post-8632688464275671559</id><published>2007-12-14T11:19:00.001Z</published><updated>2008-04-27T22:58:53.715+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Accessibility'/><title type='text'>Its our job</title><content type='html'>I cant agree with absolutely everything in &lt;a href="http://www.sitepoint.com/blogs/2007/10/16/why-accessibility-because-its-our-job/"&gt;this article&lt;/a&gt;, but it certainly does make some very good points - accessibility should not be an inconvenience!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8421903615286376978-8632688464275671559?l=nortools.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nortools.blogspot.com/feeds/8632688464275671559/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8421903615286376978&amp;postID=8632688464275671559' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/8632688464275671559'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/8632688464275671559'/><link rel='alternate' type='text/html' href='http://nortools.blogspot.com/2007/12/its-our-job.html' title='Its our job'/><author><name>James Norton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8421903615286376978.post-4042579799765151755</id><published>2007-12-13T22:17:00.005Z</published><updated>2008-04-27T23:07:07.952+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Progressive enhancement'/><category scheme='http://www.blogger.com/atom/ns#' term='CSS'/><title type='text'>Progressive enhancement</title><content type='html'>In the world of interface development today there is one technique to which I fully subscribe without hesitation or regret - &lt;span style="font-weight: bold;"&gt;progressive enhancement&lt;/span&gt;.  It is for me the guiding principle behind almost all of the work I do.&lt;br /&gt;&lt;br /&gt;Progressive enhancement can mean a number of things but in a nutshell, it involves taking a base line for a web page and layering on enhancements which are not required in order to use the web page or to understand the content of the web page.  If the browser being used can understand these additional layers, then they will be applied and will enhance the way the web page operates or looks.&lt;br /&gt;&lt;br /&gt;The base line is the HTML code of the web page.  The HTML code defines the content of the web page.  The HTML of course should be &lt;a href="http://en.wikipedia.org/wiki/HTML#Semantic_HTML"&gt;semantic&lt;/a&gt; and where possible valid.  In order to define the content of the page, the HTML code should be well structured, for example having a sensible header nesting order.&lt;br /&gt;&lt;br /&gt;Given semantic and well written HTML, the content of a web page should be accessible to any user agent.  The job of progressive enhancement is to layer on some additional "features".&lt;br /&gt;&lt;br /&gt;There are two main forms of progressive enhancement used presently.  It is in fact possible to argue that there are 3 or possibly 4 forms (and maybe even more), but the two main forms are CSS and JavaScript (I would perhaps also say that images are another main type of progressive enhancement - with well written alt attributes on image tags, the images are not necessary to understand the page).&lt;br /&gt;&lt;br /&gt;So what do these forms of progressive enhancement do and how do they work?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;CSS&lt;br /&gt;&lt;/span&gt;The way the web page looks is defined by the CSS code used to style the page.  The stylesheet uses a series of selectors to select elements defined in the HTML code and apply one or more of a wide variety of styling effects.  These include applying borders, text colours, background colours and images, sizes and many many others.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;JavaScript&lt;/span&gt;&lt;br /&gt;Any behaviours not handled by the browser by default can be added through the use of JavaScript.  JavaScript is a programming language with a C type syntax which is the language of choice for the web.  The JavaScript code can perform a massively wide variety of different operations.  These range from simple form validation scripts to whole applications such as Google Maps.&lt;br /&gt;&lt;br /&gt;Progressive enhancement gives us a very powerful structure to building web pages.  Using this technique, we create by default a separation between code for content, visual style and behavior.  We are compelled to consider the implication of our enhancements and to make visual and behavioural aspects of the web page just that, enhancements and not requirements.&lt;br /&gt;&lt;br /&gt;What will the page be like to use if the user agent does not support CSS?  How will the core functions of the page operate without JavaScript enabled in the browser?  By considering these questions, we are forced to write better HTML.  In fact we are forced also to write better CSS and JavaScript.  Everything needs to be considered carefully to ensure the separation of code remains and that the web page will be usable without the enhancements being available.&lt;br /&gt;&lt;br /&gt;Not every web page can be progressively enhanced.  In that instance, the appropriate alternative is a fallback version.  Try browsing to Google Maps with JavaScript disabled in your browser and you will be taken to a page which will work without JavaScript.   Not all fallbacks are this drastic, but a fallback allows the principle of progressive enhancement to be applied even in those few cases when the effort involved in using this approach is prohibitive.&lt;br /&gt;&lt;br /&gt;The vast and overwhelming majority of the time, progressive enhancement makes writing a web page easier.  The code will be better, cleaner and more maintainable.  The web page more accessible and inclusive.  The interface developer can be happy with a job well done!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8421903615286376978-4042579799765151755?l=nortools.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nortools.blogspot.com/feeds/4042579799765151755/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8421903615286376978&amp;postID=4042579799765151755' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/4042579799765151755'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/4042579799765151755'/><link rel='alternate' type='text/html' href='http://nortools.blogspot.com/2007/12/progressive-enhancement.html' title='Progressive enhancement'/><author><name>James Norton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8421903615286376978.post-3905309853954959090</id><published>2007-12-12T16:28:00.004Z</published><updated>2008-04-27T23:05:48.220+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Interface development'/><title type='text'>What is Interface Development</title><content type='html'>This is a very very good question.  I often get asked what Interface Development really is (other than the obvious answer).  Many people will know it as front end development.  But its easier to answer the question in the form of a skill set.&lt;br /&gt;&lt;br /&gt;I consider the core skills for a Web Interface Developer (or ID) to be:&lt;br /&gt;HTML&lt;br /&gt;CSS&lt;br /&gt;JavaScript&lt;br /&gt;User Agents&lt;br /&gt;Accessibility&lt;br /&gt;&lt;br /&gt;So what do these terms mean?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;HTML&lt;br /&gt;&lt;/span&gt;Fairly self-explanatory really.  But an ID should know about HTML and XHTML in all its different forms.  That is every widely supported doctype around.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;CSS&lt;br /&gt;&lt;/span&gt;Also self-explanatory.  Everything up to CSS 2.1 is useful at this time.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;JavaScript&lt;/span&gt;&lt;br /&gt;Another one of those obvious ones.  This is not to say that all IDs should be expert in JavaScript, but all IDs should have a good working knowledge&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;User Agents&lt;/span&gt;&lt;br /&gt;This is less obvious.  But I think an ID should know all about the most common browsers in use in the market today.  How we define common is perhaps not a subject for this post, but once you have decided what is common, an ID should be able to write code to be compatible for all of them and should be able to understand their foibles and quirks&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Accessibility&lt;/span&gt;&lt;br /&gt;Well here is something that is a bit more contentious!  IDs should ultimately be versed in best practice.  Accessibility is a large subject and deserves many posts all of its own, but suffice to say that knowing what the WCAG say is not enough.  Understanding best practice and why some approaches are good and others bad is far more useful.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;So this is what an ID is.  Its what we preach and what we practice and these are the topics that this blog will discuss.  Enjoy.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8421903615286376978-3905309853954959090?l=nortools.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nortools.blogspot.com/feeds/3905309853954959090/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8421903615286376978&amp;postID=3905309853954959090' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/3905309853954959090'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8421903615286376978/posts/default/3905309853954959090'/><link rel='alternate' type='text/html' href='http://nortools.blogspot.com/2007/12/what-is-interface-development.html' title='What is Interface Development'/><author><name>James Norton</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry></feed>
