Scoping with HTML and inline event attributes

12 Dec

Just the other day on Stack Overflow, I saw a seemingly uninteresting question with the following code:

The user’s problem was that the call to click() wasn’t executing correctly, but if he changed the name of the function it did. I’ll admit that I wasn’t really in the mood for this type of question, so I brushed it off and moved on. The subject arose again in the JavaScript chat room where Pointy, a frequent flyer in the JS tags, was attempting to get to the root of the problem. My initial thought was that the user had made a mistake, but at the same time I thought it couldn’t hurt to check it out. So I fired up jsFiddle and pasted in the code. It failed silently, so I checked a couple of other browsers with the same result.

It was obvious what was going on at this point – the <button> element has a method on it named click() and the browsers were forcing the lexical scope of the function to include properties of the current object. I made a quick and dirty change to verify this:

    <button onclick="console.log(tagName)">try it</button><br />

Sure enough, the console output was BUTTON. I’m sure many experienced developers will be unsurprised at this, knowing this is the expected behaviour all along but, honestly, I’ve never encountered this before (probably due to how I like to attach my events via JS in the first place) and I don’t remember reading it in any specification. Pointy was able to find this portion of the HTML5 spec, however:

Lexical Environment Scope
  1. Let Scope be the result of NewObjectEnvironment(the element’s Document, the global environment).
  2. If the element has a form owner, let Scope be the result of NewObjectEnvironment(the element’s form ownerScope).
  3. Let Scope be the result of NewObjectEnvironment(the element’s object, Scope).

This indicates that the JavaScript equivalent for an element contained within a form would be something like this:

element.onclick = new Function(
    "with (document) { with (this.form) { with (this) { /* function code */ }}}"

I verified this by quickly testing getElementById without referencing the document object first. It worked just fine.

Now, after seeing all this, I’m left with several questions in my head all revolving around one important question — why? — why does anyone feel like it is necessary to do all this? I can’t think of any positive reasons for it to be this way, only reasons for it not to be this way:

  • The document object and the host element for the event are both very easily accessible from within the function’s scope.
  • NewObjectEnvironment() has taken a lot of flak over the years, the only thing that uses it is the with statement and Crockford likes to remind us that with statements are harmful, like in this example, we might not know if click() belongs to the element, the form containing it, the document or the window. It’s also very inefficient.

The only reason I can think of that this is in the HTML 5 specification is for backwards compatibility. This might be the way the coding dinosaurs wrote their HTML and JavaScript 15 years ago and this feature has survived since Netscape Navigator 2.0. In my opinion, this isn’t an excuse and it should have been deprecated and removed long ago. I don’t feel so badly about it for myself, though, I’ve got by for years without even encountering this behaviour and I’m sure it will never affect me in the future, unless I’m working with someone else’s code. Just one more reason to attach your event handlers using script, I suppose.


Utilizing the awesome power of jQuery to access properties of an element

28 Oct

I’m about 35% of the way through a 100gb backup at the moment, so I thought I’d throw in a quick blog post. I’m sure this has been brought up a million (or so) times but, in my opinion, you can’t reiterate this point enough. I occasionally get my hands dirty in the jQuery tags on Stack Overflow, and all too often I see code like this:

$(".myClass").click(function () {
    if ($(this).attr("id") == "myId") {
    else if ($(this).attr("id") == "myOtherId")) {

The worst part is that this type of code is commonly given as an answer to a question. While I often feel tempted to vote down these solutions, they’re not incorrect per se, so I generally tend to post my own answer. “Why is this bad?”, you might be thinking. Well, lets simplify and break down the following code:

    if ($(this).attr("id") == "myId") {

We can separate $(this).attr("id") into 2 expressions; $(this) and attr. When you pass an argument to jQuery, it runs through the following process:

  1. Create a new instance of jQuery.fn.init(), passing this to the constructor which,
  2. initializes 4 variables,
  3. checks that the 1st argument passed isn’t a “falsy” value like null, undefined, “”, etc,
  4. looks for a nodeType property on the 1st argument passed, which is true in our case and,
  5. sets the resulting jQuery object’s context, 0 and length properties before returning the newly created instance.

Now .attr("id"):

  1. Pass the context (the collection of elements – only 1 in our case), our attribute name (“id”), value (undefined in this case), another argument named pass (true) and the jQuery.attr function to jQuery.access which,
  2. stores the length of the collection passed in as an optimisation,
  3. checks to see if the second argument is an object (a collection of property and value pairs to set on each element in the collection),
  4. checks to see if a property is being set, in our case it isn’t so it instead,
  5. checks the stored length of the collection isn’t 0 and calls the passed in jQuery.attr, passing the collection’s first element and the attribute name we tried to access. This function then,
  6. checks that the element argument passed in isn’t a “falsy” value, its nodeType property isn’t 3 or 8 (text and comment nodes respectively),
  7. checks that the pass argument was passed in (it wasn’t in this case),
  8. sets a variable that identifies whether the element passed in is an XML element (it’s not) and another that checks whether a value has been passed to assign to the property,
  9. tries to normalize attribute names into property names by looking it up in a map keeping the original name if it isn’t found,
  10. checks for a nodeType of 1 (element node), which is true in our case so then it,
  11. performs a regular expression test on the string to see if it matches /^(?:href|src|style)$/ and stores the result in a variable,
  12. checks to see if the string is “selected” to work around a bug in Safari. It isn’t, so it moves on and,
  13. checks to see if the string is the name of a property on the element, which is true in our case so it,
  14. checks to see if the set variable is “truthy”, it’s not so it skips that block and,
  15. checks to see if the element is a form element, it’s not so it,
  16. checks to see if the string is “tabIndex” to apply another workaround if true. It’s not so, finally, it feels justified to,
  17. return element[attribute].

Wow. Talk about taking the scenic route, we went through those 17 steps for jQuery to finally get to what we could have done in the first place: Of course, I’m not trying to put a downer on jQuery (it’s great and does all things!). jQuery *has* to do all this stuff for you so that you don’t run into the usual unexpected issues caused by certain implementations of getAttribute/setAttribute. Knowing which attributes are safe to access as property names means that you don’t need jQuery to do this leg work for you.

The real point of this post is that, when answering questions or helping people out with source code, try and set a good example. For the majority of attribute names you don’t need to use jQuery’s attr() to get the value of an attribute. If you’re unsure, look it up and find out if there are any specific quirks you need to know about. It might even be more efficient to work around those quirks without jQuery’s help.

I’ll leave you with an example that shows the difference over many iterations:

[iframe,js height=100px width=500px]


Cross-context isArray and Internet Explorer

26 Oct

Update, 10th July 2011 — It appears IE9 regressed this bug, so I updated the conditional compilation fix I wrote to work for all IE versions. I prefer to use feature detection where available, but I don’t see this being feasible. The bug is still present as of IE 10 PP2, but the code could easily be adjusted to check for IE less than 10 if the problem is fixed again before the final release.

I’ve been working on something lately that needs to check if a variable is an array. It’s a well known fact among JavaScript developers that, unfortunately, this is one of those situations where the typeof operator just doesn’t cut it. For a long time, many developers and libraries – jQuery, for one, used the following method to test if a variable is an array:

function isArray(v) {
    return v instanceof Array;

This checks to see if the passed in variable inherits from the native Array constructor function. The problem with this is that when we reference Array, we know that it’s a property of the current global object – in the case of a browser, it’s a member of window. Each browser window is a separate context with its own set of properties and methods, so the Array constructor isn’t the same as that of another construct. What this means for the above piece of code is, if the function is passed an array from a different context, that array isn’t an instance of the current context’s Array constructor.

Early last year, kangax (I mentioned him in the Object.keys post) came to the rescue with a robust solution that worked across frames:

function isArray(v) {
    return == "[object Array]";

This is knowledge of the specification for you. Array.prototype.toString loops through the array items and calls their toString method, returning the result as a combined string joined with a comma. Object.prototype.toString, on the other hand, will always return a string in the form of "[object [[Class]]]", where [[Class]] is the name of the internal class of the object. Because the internal class of an array is Array, no matter what context it comes from, we can be sure that this code will always work. Popular libraries like Prototype and jQuery are using this method right now. For those of you thinking, “all’s well that ends well”, I’m going to point you in the direction of the master of raining on parades; Internet Explorer.

Of course, this isn’t the case in Internet Explorer, which behaves rather strangely when passing variables between contexts. When running anything passed between contexts through Object.prototype.toString, the result becomes "[object Object]", including primitives. I’m going to go out on a limb here and speculate that this is due to JScript being heavily COM based – variables must become “host objects” when being passed (via COM) to another context.

In Internet Explorer 9, ECMA-262 5th edition comes to our rescue once again with the long overdue Array.isArray() function. Pass in a variable and it will spit out a boolean, true for arrays and false for anything else. Most other browsers also have this function at the time of writing. But we’re still left with a problem in IEs less than 9.

Potential Solution the first

I played with a lot of solutions, mostly involving duck-typing (which kangax goes into in more detail in his post), but nothing comes close to the robustness of kangax’s solution. I feel like I may have stooped a little too low in this solution, but I think that I may be justified in doing so:

(function () {
    var toString = Object.prototype.toString,
         strArray = Array.toString();

    Array.isArray = Array.isArray || function (obj) {
        return typeof obj == "object" && ( == "[object Array]" || ("constructor" in obj && String(obj.constructor) == strArray));

This runs through several checks for performance reasons; if the object’s internal [[Class]] is Array, then the extra checks aren’t necessary. The reason I feel like I’m stooping low here is that it relies on Function.prototype.toString(), a method which is defined in the spec as follows:

An implementation-dependent representation of the function is returned. This representation has the syntax of a FunctionDeclaration. Note in particular that the use and placement of white space, line terminators, and semicolons within the representation String is implementation-dependent.

Currently, all known implementations return a string in the format "function Array() { [native code] }", although the white-space within this returned string varies between those implementations, notably Internet Explorer’s has line breaks and indentation whereas others are inline. The real problem is that the string [native code] appears nowhere in the spec, so this could be changed at any given time to anything else at all. However, I can rest easy knowing that this code is safe and robust for the following reasons; a) we know that Array.toString() can’t be spoofed, because function Array () { [native code] } will throw a syntax error and, most importantly, b) we know that all current implementations of Function.prototype.toString() behave in this manner and if a future implementation changes it doesn’t matter because Array.isArray() will be present and used instead.

Potential Solution #2

Really, this is just the same solution, but with a bit of conditional compilation magic that means all other browsers can comfortably use Object.prototype.toString() while only IE will be targeted by our Function.prototype.toString(). With this, we can put to rest any fears that our code will have any unexpected repercussions in other browsers, with the added benefit that it should run faster because less checks are necessary:

(function () {
    var toString = Object.prototype.toString,
        strArray = Array.toString(),
        jscript  = /*@cc_on @_jscript_version @*/ +0;

    // jscript will be 0 for browsers other than IE
    if (!jscript) {
        Array.isArray = Array.isArray || function (obj) {
            return == "[object Array]";
    else {
        Array.isArray = function (obj) {
            return "constructor" in obj && String(obj.constructor) == strArray;

Potential Solution #3

Let’s face it, people aren’t keen on using conditional compilation. But the only other solution I could think of would be to create a new context (window or iframe), create an array in it and pass it back to the current context, then test if Object.prototype.toString() gives us "[object Object]". If it does, then we can flag that we need to use our workaround. The major downside here is that creating a new context is a pain – it would be slow and, if you’re using a frame, you’d have to add it to the document before being able to get its context. The fastest solution I could think of is to use IE’s proprietary createPopup(), but I’m only speculating that this would be faster and the solution uses a form of… eval.

(function () {
    var popup,
        toString = Object.prototype.toString,
        strArray = Array.toString(),
        hasNoClass = false;

    if (typeof window.createPopup == "object" && Function.prototype.toString(createPopup).slice(0,8) == "function") {
        popup = window.createPopup();
        popup.document.parentWindow.execScript("window.test = [];");
        hasNoClass = toString(popup.document.parentWindow.test) == "[object Object]";

    if (hasNoClass) {
        Array.isArray = function (obj) {
            return "constructor" in obj && String(obj.constructor) == strArray;
    else {
        Array.isArray = Array.isArray || function (obj) {
            return == "[object Array]";

As usual, there’s a corresponding answer on Stack Overflow. Any thoughts? Please use the comments below.


Cross browser oninput event for jQuery

18 Oct

Update: after a long period of inactivity, I didn’t realise there was a minor bug in the code. Couple that with the fact that it didn’t work in newer versions of jQuery, and I decided to remove the code from this page. However, there’s a fork of the code available at, which works with newer jQuery versions.

After posting my first technical blog post, Effectively detecting user input in JavaScript, I felt like I needed to expand on a few things that I didn’t cover. For instance, the fact that input is a bubbling event and propertychange is not, or that detecting support for input is made extra difficult by Firefox. Instead of expanding that article, I decided I would write a snippet to try and normalize the event a little better. I chose jQuery as a base for the code, mostly because I wanted to learn more about writing custom events for jQuery, but partly because I knew it would make a lot of things easier. The result is the input event plug-in below.

I wasn’t really sure where to start, but Googling turned up Ben Alman’s excellent jQuery special events post which tells you more or less everything you need to know. After that, I was able to create a basic plug-in that would provide an interface for jQuery.fn.bind("input"). The plug-in decides between attaching to input, propertychange or a host of fall back events that may or may not be supported in the browser. In short, it tries to get as much of the functionality of input as possible, but there’ll always be at least some functionality, for instance, plain keyboard input detection.

Note that the plug-in does have the following limitations in browsers that don’t support input:

  • There’s no “catch-all-changes” fallback. I had considered running a timer, when an element is focused or moused over, that constantly checks for value changes. However, this would trigger when the value of the element is changed programmatically, which may not be desired.
  • Because IE’s propertychange triggers when the value of an element is changed programmatically, that browser suffers from the problem described by the limitation above this one. It is possible that an infinite loop could be caused by always changing the value of the element in the event handler. A workaround, if you need to do this, might be to temporarily unbind whilst you change the value, rebinding after changing.
  • It currently only works with input and textarea elements. I may be able to get some support in for contentEditable elements in the future, but they don’t fire a propertychange event in IE when typing or pasting, which makes them awkward for capturing input. Firefox, Opera and IE9 don’t support the event on contentEditable elements anyway.
  • It will not work with live() or delegate(). This is due to how the propertychange event doesn’t bubble. Event delegation works as of version 1.1
  • It doesn’t work around the bugs Opera has with the input event. I’m not sure which versions are affected and it would be a pain to figure it all out. The plugin should now provide the best level of compatibility possible in all versions of Opera.


  • v1.1: Oct 24, 2011 — Fixed many browser implementation issues, introduced live/delegate compatibility, changed event special name to txtinput. see full post.
  • v1.0: Oct 18, 2010 — 1st version

The following fiddle (very basically) demonstrates the event:

[iframe 99% 300px]

Thanks to: Nick Craver, Tim Down, Ben Alman and Daniel Friesen. Please post any issues you come across in the comments.


A safer Object.keys compatibility implementation

14 Oct

I was working with Object.keys() recently to sort a list of styles returned by window.getComputedStyle() and element.currentStyle. For those of you who don’t know, Object.keys() is a new addition to the language, defined in ECMAScript 5th Edition. It is supported by recent versions of Firefox, Google Chrome, Safari and it’s also included in the Internet Explorer 9 Beta. For older browsers, we can implement our own version by extending Object.

The first thing I did was to scour the web for implementations that would work in non-supporting browsers such as Opera and Internet Explorers 7 and 8. John Resig, the father of jQuery, has an example implementation in his post about ECMAScript 5 Objects and Properties. MDC has a very similar looking version on its documentation page for Object.keys(). It looks like this:

Object.keys = Object.keys || function(o) {  
    var result = [];  
    for(var name in o) {  
        if (o.hasOwnProperty(name))  
    return result;  

PrototypeJS also has an implementation that looks like this:

function keys(object) {
    if (Type(object) !== OBJECT_TYPE) { throw new TypeError(); }
    var results = [];
    for (var property in object) {
      if (object.hasOwnProperty(property)) {
    return results;

Since I wasn’t using PrototypeJS, I decided to go with the MDC example implementation, adding a type check to the top of the function to make it more in line with the ECMAScript 5 specification. Done! …or so I thought. Turns out, my code was throwing an error in Internet Explorers 6 through 8. element.currentStyle has no such method “hasOwnProperty()”. While I did already know that, it really didn’t occur to me when I was implementing the code. In fact, all three implementations ( PrototypeJS’, MDC and Mr Resig’s) will throw this error on DOM objects in those aforementioned versions of Internet Explorer because DOM objects don’t inherit from and aren’t instances of Object (they’re actually scriptable ActiveXObjects). Internet Explorer 9 differs here, but that doesn’t matter because IE 9 already has the method we’re trying to implement.

Fortunately for us, we can borrow hasOwnProperty() from Object.prototype. Update: on a Prototype mailing list thread I started, kangax, a guy whose blog I’ve landed on quite a lot lately, mentioned that this doesn’t deal with IE’s DontEnum bug and also suggested further optimisations based on code he’d written in the past. I took his advice and improved the code further, although I chose succinctness over one or two micro-optimisations:

Object.keys = Object.keys || (function () {
    var hasOwnProperty = Object.prototype.hasOwnProperty,
        hasDontEnumBug = !{toString:null}.propertyIsEnumerable("toString"),
        DontEnums = [
        DontEnumsLength = DontEnums.length;
    return function (o) {
        if (typeof o != "object" && typeof o != "function" || o === null)
            throw new TypeError("Object.keys called on a non-object");
        var result = [];
        for (var name in o) {
            if (, name))
        if (hasDontEnumBug) {
            for (var i = 0; i < DontEnumsLength; i++) {
                if (, DontEnums[i]))
        return result;

Hurray, it works! I've also posted the solution as an answer to a question on Stack Overflow - How to list the properties of an object.


Internet Explorer’s weird vertical scrolling bug with insertBefore

07 Oct

I ran across a strange bug in Internet Explorer yesterday. It was very frustrating and took me quite a while to figure out, so I thought it might be a good idea to blog about it seeing how Google turned up no results that were of any help at all. This bug appears to only affect Internet Explorer 7 and only in Standards Mode, but is present right the way through to IE 9 if you’re using compatibility view.

I was writing a console application (more on that another day) which would take input, execute it and display the result directly above the input element, pushing it downwards. A fairly straightforward task, using element.insertBefore(), or so I thought. The containing element was a fixed height and width, after so many entries the vertical scrollbar should appear and the script should automatically scroll the area to the bottom. This is where the bug lies. In the following example, highlight the line of text with the grey background and press return repeatedly until the scrollbar appears:

[iframe 100% 220px]

If you’re viewing this page in any current browser, you can see it works fine. However, if you view the page in Internet Explorer 7 (or just view the fiddle in IE 7 compatibility view), you’ll notice that when the scrollbar appears its height sticks at a particular size and doesn’t change, no matter how many times you press return. When you scroll this “stuck” scrollbar to the bottom it shrinks, but not immediately. You have to keep scrolling until you get all the way to the bottom for the scrollbar to be the correct size. Alas, this doesn’t fix the problem, the next input will reset the scrollbar back to its stuck height.

I tried numerous ways of working around this problem – I tried using the proprietary element.insertAdjacentElement() method, I tried checking (and even setting!) the element.scrollHeight property through script and it stayed the same after each input. Finally, I found a semi-solution. Instead of inserting the result before the input element, I appended it and then used element.swapNode() to change places. Unfortunately, this presented a new problem – the input element loses focus. It’s not difficult to refocus the element, but I decided to investigate further and discover the cause of the bug. I tried to reproduce it at and I couldn’t, so I copied all my code across and made sure the bug was present. Then I whittled away at parts of the code, chopping bits out until I was finally left with the skeleton above. At this point, I just started chopping bits out of the container’s style, which looks like this:

.ContentPage { 
    border:1px solid black;

I noticed at this point that that the width style was redundant so I removed it. Surprise, it worked! No more scrollbar bug. So, if you ever run into this issue whilst testing Internet Explorer 7 then check to see if the element has the width style set unnecessarily. If you really need it to be there, then your only option may be the element.swapNode() and refocus method.

Update - it seems removing the width style caused another problem in the form of one of Internet Explorer’s “disappearing content” bugs. When I adjusted the height of the <textarea> element, the container element disappeared until I toggled another style that affected its layout. I eventually went with applying the left and right styles to solve both problems.


Effectively detecting user input in JavaScript

22 Sep

Like I said in my introductory post, my inspiration to start blogging came from Stack Overflow.  All too often, I see the same questions answered in the same way by different people and I think to myself, “No, it shouldn’t be done like that”.  Here’s one typical question:

“Hi, I’m trying to get the value of an input box as the user types into it.”

Almost instantly, you see the wrong answer appearing several times – “Use the onkeyup event handler.  It’s great and does all things!”.  The sad thing is that this is often the accepted answer.  “What’s wrong with this”, you may ask?  Well for one, the onkeyup event only fires when you lift your key from the keyboard.  The worst part is that these are often marked as the correct answer by the person asking the question.  This might not be a huge problem for you, but you might also be unaware that there can be a varying delay between when the value of the text input changes and when the user lifts their finger from the key.  Take the following example, type and might notice a slight delay before the text input’s value is copied to the div below it:

[iframe 100% 60px]
View source

Now hold your finger down on a key and let your OS’s input repeat trigger.  Notice how the div doesn’t update even though extra characters are added to the input?  This doesn’t feel very professional, does it?  Often, I provide a solution to these questions by means of a timer in the onkeydown event handler.  This still only handles input from a keyboard, but it feels less clunky as the update is almost instant.

[iframe 100% 60px]
View source

The timer is set with a 0ms value so that it is queued to be executed almost immediately.  I say almost, because all browsers have a minimum delay on setTimeout and setInterval (Firefox’s is 4ms), but it’s still a better solution than waiting for the onkeyup event and a much faster response for the user.  However, this still doesn’t deal with input that doesn’t involve a keyboard. What other types of input? How about context menu actions; cut, paste, undo and redo?   Drag and drop?  There have been events to handle some other kinds of input change for a while – several browsers support the onpaste, oncut and oncopy events – but they’re non-standard and some vendors are just too stubborn to implement them.

Enter the HTML 5 event, oninput.  This event really makes sense – one handler to rule them all, and browser support is looking great so far.  There’s just one exception to the list… wait for it… Internet Explorer!  So we’re back to square one.  Or are we?  Well, the oninput event can be emulated in Internet Explorer by handling the onpropertychange event.  This event will fire when any property changes on a DOM element, so all that’s needed is a simple check to make sure the property is element.value.  A proper implementation would check the input’s type property too, since on checkboxes and radio inputs the oninput event should fire when the state changes.  So let’s check out our latest solution, go nuts with copying, pasting, dragging and whatever!

[iframe 100% 60px]
View source

And there you have it.  If you need to support older browsers (note that this works in IE6+), you can use your favourite method of event detection to fall back to onkeydown with a timer. At least then you’ll have at least some of the desired functionality. The added benefit here is that this solution provides us with a method of validating user input when it is pasted or dropped into the box as well as typed, so you don’t have to wait until the change event to check for this.  I might touch on that in a later post, I think I’ve written enough for one day.

Note: There’s a bug in Opera 10.x where oninput doesn’t fire on certain elements for certain actions (like cut, copy, paste, drag & drop).  It does work fine for textarea elements, however, and this event still works better than the onkeyup even with this setback.  I’ve reported this issue to the Opera developers and hopefully they’ll fix it soon (edit: it’s fixed in Opera 11 alpha).  See also the bug affecting Firefox’s implementation of oninput.


Welcome to the blog of Andy E’s head

21 Sep

I’ve tried blogging once or twice in the past, but I can never think of anything to write.  Then, I started participating on, answering questions mostly about JavaScript.  I never really considered myself to be an expert on the subject back then because I really only ever dealt with JScript, Microsoft’s implementation of ECMAScript.  I still don’t really know if I could call myself an expert on the subject, but I do think that I can get my head around most of the problems I face when writing scripts daily.  I’ve certainly learned a lot since joining the site.

Back to  I’m ashamed to say that I didn’t come up with the name by myself, I was thinking about it for a while and I couldn’t come up with anything.  So I headed, no pun intended, over to (yes, I’ll probably talk about Stack Overflow a lot) and asked for some ideas.  The transcript went a little like this (to clarify, my screen name comes from my Futurama-esque head-in-a-jar avatar):

Andy E’s head: I’ve finally decided to start blogging, but I’m not sure what to call my blog :/
Fosco: what’s it about? What name are you using as the author?
Andy E’s head:
Well, my area of expertise is JavaScript. Most of my blog posts will probably be inspired by Stack Overflow questions, because it’s usually when I see certain questions that I want to go into a big ramble about the subject
Piers Myers: what about “Andy E’s Head Said …”

Others liked this suggestion, and so did I.  I didn’t want the domain name to include my name though (no resale value!), so I came up with the variation “What the Head Said”.  So here we are, one more JavaScript coding blog with no readers.

Well, enough meta-blogging for now.  I’m going to have a play around with this WordPress thingy and see if I can write some actual useful content.