Wednesday, February 15, 2006

Happy birthday "Ajax"

Well, almost. February 18th is the official one-year anniversary of Jesse James Garrett's essay that coined the term "Ajax" to describe what applications like Google Maps were using under the hood.

Thus rekindling interest in what some longtime web developers have pooh-poohed as old news: DHTML. But man. Books. Articles and tutorials. Conferences! Workshops! And the prime indicator that a concept has gained serious traction, haters!

Not bad for something once considered just a few short years ago to be too broken, unevenly-supported, and often downright ridiculous to be of any use.

Tuesday, February 14, 2006

Y! Design Pattern Library

While it's awesome that Yahoo! has released a suite of JS tools, I'm actually more enamored of the Yahoo! Design Pattern Library.
The Yahoo! Design Pattern Library is an evolving set of sophisticated design guidelines for building web pages and applications. Our design patterns do not require the Yahoo! UI Library components, although using our UI Library can help you more easily implement the patterns described in these pages.
Very cool.

Safari quirk: Copying innerHTML

Here's a fun one. Given the following HTML, let's attempt to copy the contents of div1 to div2, then grab a reference to the SPAN element "foo."

<div id="div1">
  <span id="foo">Foo span</span>
</div>

<div id="div2"></div>

The easy way out is to just copy innerHTML from one element to the other, then destroy the contents of the original element:

document.getElementById('div2').innerHTML = 
    document.getElementById('div1').innerHTML;
document.getElementById('div1').innerHTML = '';
alert(document.getElementById('foo'));

In most browsers, the alert dialog displays "Element SPAN" or something similar. But in Safari 1.3 and above, the dialog displays null. Why?

For a brief moment, when we copy the innerHTML, we create two SPANs with identical IDs of "foo." Even after we destroy the contents of div1 (leaving only the one SPAN), the DOM is screwed up enough to confuse Safari, which continues to return null even after the DOM is "fixed." By contrast, Firefox for OS X is far more forgiving.

The solution seems to be: duh, don't copy from element to element. Instead, hold the contents in a variable until it's safe to reinsert them into the page:

var tempHTML = document.getElementById('div1').innerHTML;
document.getElementById('div1').innerHTML = '';
document.getElementById('div2').innerHTML = tempHTML;
alert(document.getElementById('foo'));

The dialog should now display "Object SPAN" in Safari. Of course, astute JS developers would probably prefer to skip using innerHTML altogether