doug crockford has a posse.

Firefox getComputedStyle Table Margin Bug

firebug screenshot

There’s a bug in Firefox when computing table margins using getComputedStyle; it always returns 0px. See the test case.

The bug also effects current versions of Firebug (case 171, as well as YUI’s getStyle method (my library of choice.)

Thankfully, there’s a workaround. While technically you could alter the display property of your table to ‘block’, you’ll probably find that to be less than ideal in most situations. A more graceful approach, if subtly less performant, is to clone the table and obtain the desired measurement from the clone. (Note: It is not necessary to perform a deep clone.)

View the workaround.

Update (4/2/2008):

I posted an inquiry to this bug on the ydn-javascript mailing list hoping to gain some insight from the the yui team. Matt Sweeney (author of Dom, Selector, and Animation—to name a few) rose to the occasion and did a little research into the issue. He found that while this bug is fixed in the latest build of Firefox 3, that apparently Opera and Safari diverge from Firefox in their interpretation of CSS2 Specification and that “perhaps some clarification is needed here for the sake of x-browser consistency.”

By the way, Matt’s response is one of the reasons it’s worth being a member of the ydn-javascript mailing list even if you don’t work with yui on a daily basis. Granted, you’ll have to dig through a lot of posts that might be irrelevant to you, but every now and again you come across a gem of insight which might help you become a better developer.

Javascript: The Good Parts

javascript_the_good_parts.jpgThere is perhaps no one individual who has had more impact on modern JavaScript than Doug Crockford. As such, I’m thrilled to see the Godfather has a soon-to-be-released O’reilly book, JavaScript: The Good Parts. (The Butterfly Book!)

I’m secretly hoping it’s not a regugitation of all the things he’s already said/written, regardless it’s been pre-ordered!

Amazon’s Lack of Anticipatory Design

As a wedding gift, my employer hooked us up with a fabulous getaway to Sierra Mar in Big Sur. Sierra Mar is easily one of the Bay Area’s top restaurants, and among the highest rated in Zagat’s Guide. (The year we went, it ranked #1 in Romantic Decor, and #3 in Food.) Needless to say, it wasn’t cheap—we spent about $350, and neither of us drink!

What I most appreciated about our visit to Sierra Mar, was not the exquisite food or breathtaking views, but the ability of our server to allow my wife and I to focus on the goal of our dining experience (one another!) Somehow our server, while yet friendly and engaging, was extremely non-obtrusive and attendant to our every need, anticipating every want and desire.

What a talent; we tipped big.

With this anticipatory service in mind, I’m at lost why Amazon, being the model-citizen of user-tested design, cannot seem to anticipate the simple needs of a user logging in to make a purchase.

Amazon’s Login Screen

Why is that upon entering my username, and beginning to type my password, they cannot afford me the courtesy and assume I’m a returning customer?

How is this “quick and easy?” Come on Amazon, toggle that radio button onkeypress. Earn your tip!

Top JavaScript Books of All-Time

The Best Books on Javascript

5. Pro JavaScript Techniques by John Resig. John’s jQuery library is a thing of absolute beauty—the source is an example of javascript’s utter sexiness. Now, as a whole I found this book a bit disjointed, nevertheless it’s recommend because it attempts to tackle difficult subject matters like closures and event handling, and does so in an accessible way, for the novice transitioning to advanced javascript.

4. Dom Scripting by Jeremy Keith: Jeremy provides a nice introduction for the beginning web developer with no background in javascript. Published by Friends of ED, it’s like reading the USA Today—fun and light!

3. Professional JavaScript for Web Developers by Nicholas Zakas. Zakas is an excellent developer and provides an exhaustive introduction to the javascript programming language. While his book is a few years old, it’s still a reliable starting point. (More, an update is in the wroxs—uggh, forgive me!)

2. Pro JavaScript Design Patterns by Dustin Diaz and Ross Harmes. The Gang of Four has become the Gang of Two! Dustin’s an excellent communicator, his personal weblog is a staple for those desiring to learn javascript, and Ross is a worthwhile co-author. They setout to tackle a difficult and controversial topic, and in so doing bring advanced programming principles to the much needed discipline of front-end engineering. Great stuff, but be prepare to be stretched!

1. JavaScript, The Definitive Guide by David Flanagan: It’s the only book on JavaScript that the venerable Doug Crockford is willing to endorse. What more do you need to know? If this book isn’t within arms reach at all times, you’re not worth your salt. (I’m also a fan of the pocket reference.)

Sell Me Something

…add Customer Retention to the desired and never-ending skillset of a front-end developer.

Mint gets it wrong. Again. Upon deleting my account, they had one last opportunity to woo me and they wasted it. Save for laziness, I have no idea why they’d redirect me to their login page, after all, I JUST DELETED MY ACCOUNT!

As long as a customer is still standing on your property, continue to present them with buying opportunities. Retention is far cheaper than bringing them back.

Sell Me

Making full use of the Arguments object

In Javascript, arguments are the variables passed to a function. We might think of a soda machine that accepts coins that are then processed, returning your favorite carbonated beverage. Likening this to a function, the coins are arguments.

In general these arguments are accessed by named variables as represented in the following example by str1 and str2:

function concatenateTwoStrings (str1, str2) {
    return str1 + str2;
}

concatenateTwoStrings('foo', 'bar');
// returns 'foobar'

It's not always convenient however to access our arguments in named manner. As such, Javascript provides the Arguments object. This "Array-Like" object is accessed like this:

function concatenateTwoStrings () {
    return arguments[0] + arguments[1];
}

concatenateTwoStrings('foo', 'bar');
// returns 'foobar'

The power of using the arguments object is evident when we're not sure how many arguments will be passed into our function. For instance, we might write a function that will concatenate an unknown amount of strings.

function concatenate () {
    var result = '';
    for(var i=0; i <arguments.length; ++i){
        result += arguments[i];
    }
    return result;
}

concatenate('douglas', 'crockford', 'has', 'a', 'posse');
// returns 'douglascrocfordhasaposse'

Nice, right? Well, sort of. To actually concatenate a large amount of strings in this manner is very slow. In JavaScript, it's actually significant faster to first add each string to an array, and concatenate them using the array's join method.

function concatenate () {
    var result = [];
    for(var i=0; i <arguments.length; ++i){
        result.push(arguments[i]);
    }
    return result.join('');
}

concatenate('douglas', 'crockford', 'has', 'a', 'posse');
// returns 'douglascrocfordhasaposse'

Now you might be thinking we could just us the join method on the arguments object. The problem is, though Arguments has a length property, it's technically not an Array. It's known as "Array-like." That said however, in JavaScript, the methods of an object are not restricted to be used only by itself. Javascript provides two amazing little methods, call and apply, that are properties of EVERY function, and will allow us to essentially hijack them from their parent, and use them as if our desired object was their parent.

Check this out:

function concatenate () {
    return Array.prototype.slice.call(arguments).join('');
}

concatenate('douglas', 'crockford', 'has', 'a', 'posse');
// returns 'douglascrocfordhasaposse'

Now that's pretty obscure JavaScript but it's so so hot.

Now, to finish up here, we might want to provide ourselves a little flexibility in how we want each string concatenated. For instance, we might want a space or comma-separated string instead of everything simply merged together.

function concatenate (separator) {
    return Array.prototype.slice.call(arguments, 1).join(separator);
}

concatenate(' ', 'douglas', 'crockford', 'has', 'a', 'posse');
// returns 'douglas crockford has a posse'

Don’t make me think

All design ought to be to be consistent and clear, but all the more when it comes to error handling. The reason is simple and two-fold: errors are both unexpected and disruptive. As such it's critical that designers curb potentially agitating interruptions with accurately descriptive error messages, immediately refocusing the user on the problem, and making the process of getting back on track as quick and painless as possible.

With this in mind, today Mint failed me. For the purpose of posting a screenshot, I changed my email address here, but indeed it was my password that was incorrect, not my username that caused the error. Yet upon first glance, without reading the fine-print, you're forced to conclude it was the username.

Mint’s Inconsistent Error Handling

I can only hope they're more detail-oriented with the management of my finances! ...not good.

Cross-browser Javascript Profiling with YUI

Soon the fabulous YUI team will release a skin for their profiler tool. This release will hopefully bring profiling mainstream, if Firebug hasn't done it already (and what sadly Venkman failed to do.) More importantly, it will bring this indispensable benchmarking technique to all A-grade browsers and platforms, and in a manner that will be accessible to the average web developer.

Hot stuff!

But why wait? This is not difficult to accomplish with the tools already they've provided us.

To start, you'll need to include a few dependencies from Yahoo.

<link type="text/css" rel="stylesheet" href="http://yui.yahooapis.com/2.4.1/build/logger/assets/skins/sam/logger.css">
<script type="text/javascript" src="http://yui.yahooapis.com/2.4.1/build/utilities/utilities.js"></script>
<script type="text/javascript" src="http://yui.yahooapis.com/2.4.1/build/logger/logger-min.js"></script>
<script type="text/javascript" src="http://yui.yahooapis.com/2.4.1/build/profiler/profiler-beta-min.js"></script>

Next, we'll obviously need something to profile, so let's write a simple function that creates a div from scratch. We'll then register the function with the Profiler tool.

function createDiv (){
   return document.createElement('div');
}

YAHOO.tool.Profiler.registerFunction('createDiv', window);

That's it. We're already to run our test, so let's call createDiv() a bajillion times to create some data.

for(var i=0; i<5000; ++i){
   createDiv();
}

Profiler offers you a bunch of different methods to slice and dice your results. Most likely you're gonna want to find the average duration (getAverage), but you can also retrieve the maximum, minimum, and even how many times the function was called.

Now let's finish up and get some result.

//Create a new instance of the Logger widget (we'll use this panel to display our results.)
var logger = new YAHOO.widget.LogReader('logger');

var avg = YAHOO.tool.Profiler.getAverage('createDiv');

//Write the results
YAHOO.log('The average duration of creatDiv() was: ' + avg);

Try it out!

Yuidocs.com : Faster access to YUI Documentation

Good programmers are lazy, and while I might not be good, I'm surely lazy. I got tired of typing http colon slash slash developer dot yahoo dot com slash yui slash docs and instead bought yuidocs.com which auto-forwards for me. Enjoy!

YUI Documentation

if you’re not serious, don’t ask.

Grandparents are obsessive about obtaining printed photos of their grandchildren, and my parents are no exception. They've obviously decided to spend my inheritance and fill their albums instead.

Yet regardless of their compulsion, I've been completely unsuccessful to lure them to Flickr, and as such, my wife and I have had to upload our photos to both Flickr and Snapfish—it's a horrible shame.

And as much as I'd like to pass this off as my parents' problem, here's just one example how users might become agitated by Flickr's poor ecommerce process:

Flickr frustrates their customers

Don't frustrate your users, especially paying ones.

← Before