Back in the grand old days of linear programming, one of my IT mentors told me something I’ve never forgotten: “The easiest code in the world to write is bad code.” It was true then; it is even truer in our nonlinear, object-ridden age, when programs are so multifunctional and cross-platformed. We just don’t think about it as much because object-oriented programming is, in general, so robust and forgiving of error. It’s possible, even easy, to write embarrassingly bad code that runs just fine.
But this is no excuse for sloppy work. (Wait till someone tries to upgrade that sloppy app that “runs just fine.”) And the rapid acceleration of Web growth heralds an end to the forgiveness of object code. Web pages themselves must, in these dynamic times, be ridiculously cross-platformed. And therein lies danger for the DHTML programmer.
DHTML coding commandments
As I discussed in my previous article, you need to avoid a couple of pitfalls when writing for Web applications. First, HTML code, and DHTML code in particular, must function consistently on multiple Web browsers and on multiple versions of those browsers. Second, where compatibility is not possible, a properly written Web app shouldn’t crash but should fail gradually, preserving as much function as possible. We’re going to look at some coding guidelines to help you meet these goals.
Before we get underway, however, a note of caution: Applying these coding principles can’t help but enhance your Web apps, but it’s not so easy to actually apply them. They build on one another, so attention to detail is essential, over and above committing to the general principles to begin with. And since the “dynamic” in DHTML covers a number of Web technologies—scripting, style sheets, and the DOM, to name the big ones—they must be applied case by case.
The art of browser-sniffing
An essential first step in writing robust DHTML is building browser detection into your code and writing conditional variations on your critical functions so that your pages will have full functionality across a broad spectrum of browsers. It’s true that this is a lot easier since more current Web development packages anticipate newer versions of the most prominent browsers. But it’s better in the long run if you anticipate a broad audience for your pages, going a little more native and using browser-detection techniques from the earlier days. Your apps are then more certain to work correctly on older systems.
It’s tempting to approach a DHTML project with nothing more than the latest Internet Explorer and Netscape Navigator in mind. But the browser world is much broader than this. At last count, more than 200 browsers were in broad deployment, including lesser-used browsers that don’t support graphics (Lynx, for example) and browsers that run on operating systems other than Windows and Mac. Hundreds of thousands of copies of earlier releases of Internet Explorer and Netscape Navigator are also still in service, and these may not support all the features that you intend to use in your application.
A good baseline level for assumed browser currency is to write for Internet Explorer 4.0 and Netscape Navigator 4.0 and above, although of course any decision in this area is specific to your application. Sniffing out the browser running the code can be as general or as specific as you need it to be. For example, if Netscape Navigator is running the code, and you just need to know whether it’s Navigator 4.0 or higher, all you have to do is look for a layers object. Test for the presence of that object and you’ll know where you are. If you need to know the specific version that’s running, the navigator object will give you more detail. It has a property called appVersion that will give you everything you need.
To pin down the presence of Internet Explorer, test for the object document.all. If it’s there, you’re on Internet Explorer, and your version is 4.0 or higher.
You can use many similar tests and browser-specific detection tricks. Consult the documentation on specific versions of browsers to learn more. Be sure in writing your code that you cover every browser and version prevalent in your user community, so that you can write conditional variations on all the critical functions of your page.
Creating the conditional branches for your functional code, once you’ve sniffed out the browser, can be done a number of ways, many of which you can come up with off the top of your head. But in addition to these, there’s a neat trick you should know.
The general idea is called conditional commenting. This is the one of the easiest conditional coding techniques imaginable. It works simply: Embed code that uses features specific to newer browsers within the comment tags of older browsers. The net effect will be that older browsers (incapable of running the code) will ignore that section of code, while newer browsers will do the opposite, ignoring the tags and running the code.
There’s also an enhanced version of conditional commenting. This is a good choice if you’re writing primarily for more modern browsers, such as Internet Explorer 5.0 or equivalents. It employs the concept mentioned above, utilizing both the old-style comment tags:
<!– comment goes here–>
and a newer variation, specific to IE 5:
With this tag, code can be enabled and disabled for Internet Explorer 5 by toggling with these comment tags:
<![if ! IE 5]>
I am an object being displayed by a Web page running on some browser other than Internet Explorer 5.
<!– [if IE 5]>
I am an object being displayed by a Web page running on Internet Explorer 5.
You can do a lot more, in the course of scripting, to optimize your application. For instance, it’s easy to externalize scripts and even to activate them based on the OOP attributes of screen objects. We’ll examine these subjects down the road.