Posts Tagged ‘JavaScript’

Stoyan’s Performance Advent Calendar And Me

Sunday, December 20th, 2009

Stoyan Stefanov decided to release a post a day during the advent season in an effort to bolster our budding performance community.

He was kind enough to let me participate, not once but twice! My first contribution was called, JavaScript Loading Strategies and my second, which is out today is called, Extreme Performance Optimization.

I hope you enjoy reading them, and be sure to check out the other posts in Stoyan’s performance advent calendar as well!

  • Share/Bookmark

Introducing 140 char (or less) JavaScript programs

Friday, July 18th, 2008

Today I got tired of seeing yet another onclick="obtrusivejavascript()" in HTML so I wrote a little program in protest. What I wanted to do though was to post the program to Twitter which has a 140 character limit so it was mildly challenging. Here it is:

Fully expanded:

var elems = document.getElementsByTagName("*");
for (var i = 0; elems[i]; i += 1) {
    if (elems[i].getAttribute("onclick")) {
        elems[i].onclick = function () {
            alert("FAIL!");
        }
    }
}

Compressed for Twitter:

var x=document.getElementsByTagName("*");for (var i=0;x[i];i++){if (x[i].getAttribute("onclick")){x[i].onclick=function(){alert("FAIL!");}}}

I invite you to continue the trend. Write 140 character (or less) JavaScript programs and post them to Twitter then post a link here in the comments. If the trend grows, I’ll build a small site to host the activity.

I’ll go first!

  • Share/Bookmark

A Nuance of Preventing Default

Friday, May 16th, 2008

One of the most common operations when assigning event handlers is to prevent the default action the event normally triggers.

In the case of an anchor for example, the click event of an anchor triggers the default behaviour of following the URI specified in the href attribute. So the browser’s default action when clicking the “Fluffy Bunnies” anchor below, is to send the user to http://wait-till-i.com.

<a href="http://wait-till-i.com">Fluffy Bunnies</a>

When coding unobtrusive JavaScript awesomeness however, following the URI isn’t always the desired action that we want when the user clicks on an anchor. Thus, the event handler that is assigned to the anchor needs to stop the default behaviour. This can be done in two ways: by having the handler return false, or using the event object’s preventDefault method (except for in IE which makes you set returnValue to false within the event object).

Returning False

var a = document.getElementsByTagName("a")[0];
a.onclick = function () {
    return false;
};

Preventing Default

var a = document.getElementsByTagName("a")[0];
a.onclick = function (e) {
    e = e || event;
    if (e.preventDefault) {
        e.preventDefault(); // All browsers except IE
    } else {
        e.returnValue = false; // IE
    }
};

Having to use an if/else block every time you want to use preventDefault/returnValue is very cumbersome. This is where a good JavaScript library will serve you well by wrapping this functionality up in one easy function call. The YUI Library for example allows you to do this:

var a = document.getElementsByTagName("a")[0];
a.onclick = function (e) {
    e = e || event;
    YAHOO.util.Event.preventDefault(e);
};

The nuance: using preventDefault in debug vs. release code

In my opinion, preventDefault should be used in two different ways depending on whether you’re in debug mode or release mode. The reason for this is simple, when you’re debugging, the last thing you want is for the browser to leave your page when something breaks on clicking an anchor. Why? Because normally (in Firebug anyway) the error message that was generated disappears once you leave the page. Take the following code example:

var a = document.getElementsByTagName("a")[0];
a.onclick = function (e) {
    e = e || event;
    // Lots of buggy code here
    YAHOO.util.Event.preventDefault(e);
};

In this example, the code will break before preventDefault has a chance to execute. Upon its breaking, the browser will fall back to the anchor’s default behaviour and leave the page to follow the anchor’s URI. That can be annoying when you’re debugging, but it’s exactly what you want in a production environment. You don’t want links to stop working in production when some JavaScript breaks. Rather, you want the script to degrade/break gracefully and give the user access to a valid URI. So the above example is fine for production. While debugging however, the following sequence is preferable:

var a = document.getElementsByTagName("a")[0];
a.onclick = function (e) {
    e = e || event;
    YAHOO.util.Event.preventDefault(e); // Stop the default action before buggy code breaks
    // Lots of buggy code here
};

I hope you’ve found this nuance useful, I know it’s saved me lots of headaches when debugging.

  • Share/Bookmark

Have JavaScript, Will Travel

Thursday, May 1st, 2008

The technology of the web is maturing. However slowly and clumsily, it is maturing. The web of today looks nothing like the web of ten years ago. Most notable are the advent and widespread adoption of Web Standards, and more recently the mushrooming popularity of JavaScript due largely to Web 2.0 mania.

The trouble though, is that almost nobody knows how to program in JavaScript. Relative to the number of web designers out there (those who only know HTML and CSS) there are very few front-end web developers (those who know HTML, CSS and JavaScript). And this isn’t wild hand waving. I know it to be true because I do a lot of interviewing of potential candidates where I work. Nearly everyone that I meet says flat out, “I don’t know JavaScript.” And those that say they do, admit to only being able to work with existing code, i.e. changing a value here and there. Very few can code applications from scratch. Yet that’s exactly what’s needed, which means there’s a shortage of qualified people.

You may be thinking, “isn’t JavaScript something better left to real programmers?” The answer is a resounding no! First of all, JavaScript programmers are real programmers. This ain’t 1996, and this ain’t your daddy’s JavaScript. Things have changed over the past ten years, a lot. Secondly, good programmers specialize. Simply put, the more time you invest in understanding the ins and outs of JavaScript, the better you’ll be at it. JavaScript is actually unique from other programming languages in that it’s implemented across a slew of competing browsers (it’s the only browser scripting language available) and is deployed across more computers than any other programming language could ever dream. The very fact that competing browser makers write their own implementations of JavaScript means there will be differences. Knowing those differences and the inevitable quirks that each implementation has is a definite asset to any aspiring JavaScript Code Ninja. To say nothing of the time, hassle and security risks that knowledge will save you.

So if you’re interested in jumping onto the JavaScript bandwagon, here are a few things to remember:

  1. Don’t learn by viewing source, learn from the experts. Here are a few starting points: Douglas Crockford’s JavaScript, Christian Heilmann’s Blog, John Resig’s Blog, YUI Theater, JavaScript articles on SitePoint.
  2. Find out what Unobtrusive JavaScript is and write all your code that way.
  3. Avoid copying and pasting, type everything out long hand. This is a self-teaching technique I often use. Rather than using the clipboard, I place both windows adjacent to each other and retype the line I want. This forces the brain to better absorb the information. Trust me, it works if you get into the habit of doing it.
  4. Invest in a few good books. Here are a few to start you off, JavaScript: The Definitive Guide, JavaScript: The Good Parts, The Art & Science of JavaScript (full disclosure, I co-authored that last one… hey who ever said self-promotion was a bad thing?)
  5. For the love of all that’s good and decent, install Firebug. Also know that the debugger that comes with MS Office (yes, oddly enough there is one in there) is orders of magnitude better than the one you can download for free from Microsoft.

Now get coding!

  • Share/Bookmark

Worry Free JavaScript Internationalization (i18n)

Sunday, April 13th, 2008

There’s a right way and a wrong way to go about i18n. Just to be clear, I don’t subscribe to the idea of right vs. wrong unless there’s a good reason for it, otherwise I just chalk it up to preference. Sometimes I consider something as a matter of preference until someone points out a compelling argument either for or against it. It’s with that perspective that I address the issue of i18n.

I’ve often found that when first confronted with the need for i18n, the temptation is to do something like this:

var lang = getLang();
var msg = "";
if (lang === "en") {
    msg = "Hello world!";
} else if (lang === "fr") {
    msg = "Bonjour Monde !";
}

That will work fine, but what happens if there’s a bunch of text throughout the app that needs i18n? That’s a whole lot of if/else blocks. And what happens if you suddenly have to support three, four or fifteen languages?

Object literals to the rescue! JavaScript has this wonderful little thing called the object literal represented by a set of brace brackets: {}. It creates a singleton object that can be nested within other objects and can contain pretty much anything. The syntax is very straight forward, all you need are key/value pairs separated by commas:

var data = {
    helloworld: {
        en: "Hello World!",
        fr: "Bonjour Monde !"
    }
}

In this case we have an object being assigned to a variable named data. That object in turn contains another object named helloworld. Finally, helloworld contains two strings, one named en and the other fr. These values can now be accessed like so:

msg = data.helloworld.en;

Of course what we need is to be able to dynamically access the language node in our dataset. This is where index notation comes to the rescue. So far we’ve accessed our data via dot notation, but it’s also possible to access data via index notation like so:

msg = data.helloworld["en"];

I’m sure you can see where this is going. Now that we can specify the last node of our dataset with a string value, all we need to do is substitute it with a variable.

var lang = getLang();
msg = data.helloworld[lang];

Here, getLang determines what the current language setting is and returns a string value accordingly. Once that string value has been received, it can be placed into the index portion of our data object and voila! No more if/else logic, and this technique can be used to support an infinite number of languages without ever having to modify the code itself. You want Spanish? Just add an sp node to your dataset. That’s it, that’s all.

Enjoy!

Update: I neglected to mention that I implemented this solution in the context of a Yahoo! Widget where all of the data is stored locally on the desktop. This solution doesn’t make much sense in the context of a website since you’ll be sending way too much data that won’t be used down the pipe. Thanks to AB for pointing out my oversight.

  • Share/Bookmark