Before looking at some code, there are three development approaches that should be discussed in detail. Which approaches you take—and you can simultaneously take more than one—impacts the code you write and, more importantly, the end user’s experience.
graCeFul degradation
The converse of the script element, used to add JavaScript to any HTML page, is the noscript element. It’s used by a page to provide an alternative message or alternate content when the browser does not support JavaScript:
<noscript>Your browser does not support JavaScript!</noscript>
Key developMent approacheS 39
ptg7799847 Anything placed within the tags will be shown to the user should JavaScript
not be enabled. This includes text and/or HTML.
Statistics vary, but generally speaking, somewhere around 1–3 percent of all clients accessing Web sites are not capable of executing any JavaScript for one reason or another. This includes people who:
J Have purposefully disabled JavaScript in the Web browser
J Are running NoScript (http://noscript.net), a Firefox extension that implements a white-list approach for allowing JavaScript to run on pages in a given site
J Are using screen readers (i.e., assistive devices for the vision impaired)
J Are using mobile or gaming device browsers
J Are connecting via console software that doesn’t support JavaScript (such as the command-line wget or curl)
J Aren’t actually people, but are really a bot, such as a search engine That’s a really small percentage of the overall market, but it’s up to you to decide how to best handle these situations. There are three approaches:
1. Pretend non-JavaScript clients don’t exist.
2. Apply graceful degradation.
3. Apply progressive enhancement.
I’m not here to tell you how to do your job, but the first option isn’t a good one, especially with the increased usage of mobile and gaming devices, let alone whatever new technologies are coming down the pipeline. And yet, a surprising number of developers don’t recognize that some users cannot execute JavaScript.
With such sites, the end result may be a broken page, without any explanation as to what’s wrong. There are certainly valid reasons why a Web site would require JavaScript, but non-JavaScript clients need to be informed of that requirement. Not preparing for that possibility is bad for the end user and it reflects poorly on the Web developer (and/or company whose site it is).
ptg7799847
For years, the second option was the most common response, and is still seen occasionally. Graceful degradation is a tactic where you design a site to be fully functioning as you want it to be, and then provide an alternative interface, or just a message indicating the need for JavaScript, to devices that can’t use the site as you had designed it. Sound familiar? Yes, this is in effect what the noscript tag does.
Graceful degradation is a big improvement over merely ignoring the problem. The main difference is that graceful degradation does let the user know that a problem exists and what the solution should be (i.e., come back with JavaScript enabled).
Still, there is a better approach, called progressive enhancement.
Progressive enhanCeMent
Progressive enhancement is a term first coined in 2003 but whose adoption still continues to this day. Progressive enhancement takes the opposite stance as graceful degradation: Whereas graceful degradation begins with the desired functionality and offers alternative content if the full functionality isn’t supported, progressive enhancement starts with a baseline of minimum functionality and then improves upon that—enhances the user’s experience—by adding “rich” features only if the client supports them (Figure 2.7). Not only does progressive enhancement ensure that all clients will be able to use your site, I personally find it easier to develop using this approach.
Progressive enhancement involves not just JavaScript but also CSS. There are entire books dedicated to the subject of progressive enhancement (such as Design-ing with Progressive Enhancement, New Riders, 2010), and I cannot spend too many pages on the subject here, but the process you need to understand is simpler than you might think.
To start, you should use standards-compliant, well-structured, clean, semantic HTML. Semantic HTML uses HTML tags to clearly indicate the intent or meaning of content, not how the content should be presented. For example, you should stop using the i tag to italicize text, and use em, for emphasis, instead. It may seem
fiGURe 2 .7 Progressive enhancement applies dynamic layers on top of base functionality.
Key developMent approacheS 41
ptg7799847 like a fine distinction, but with em tags, there’s no absolute browser sense of what
emphasis means in terms of styling. Speaking of styling, with semantic HTML, all of the presentation gets moved into CSS, where it belongs. In situations where there are no tags that indicate the meaning of a page component, classes are used for that purpose. In fact, commonly used semantic classes such as footer, header, and nav were inspirations for new elements in HTML5.
Once you’ve created a nice semantic HTML page, you should validate it, to be certain that it’s problem free and unlikely to send browsers into Quirks mode. You should also test that the HTML and base CSS alone renders properly in the browsers you’re targeting. Once you’ve done all that, you can enhance the experience for the clients that are capable of handling more modern features. As an example of this, let’s turn back to the registration form example discussed in Chapter 1.
The baseline functionality for that form, as well as for all forms, is that when the form is submitted, the form data is sent to a server-side script. The server-side script performs the validation and then reacts accordingly. For a registration form, this means either there were no errors and the user is registered in the database, or there were errors, and those are reported to the user, so that the user may correct the mistakes and resubmit the form (see Figure 1.3). The next step in the progres-sive enhancement process, after creating the semantic HTML page that contains the form, would be to create the server-side script that handles the form. This completes the baseline functionality, and involves no JavaScript (or high-end CSS).
It’s in this regard that I think this approach is easier: because you first confirm that the simple process is working, before trying the more complicated approach (e.g., Ajax, which is a bit harder to debug).
The final steps are to apply CSS and JavaScript to add layers of more advanced features and design, but only when the browser supports it. The focus in this book is just on the JavaScript, of course. To determine whether or not a browser sup-ports a feature, the modern JavaScript programmer makes use of object detection, as already mentioned in Chapter 1. This approach creates reliable cross-browser JavaScript, regardless of the browser type or version. And, object detection is bril-liantly simple: Check to see if the browser can support feature X, and if so, then use feature X. You’ll see a specific implementation of this in just a couple of pages.
Through this process, applicable browsers will be progressively enhanced and no one will be left out. This is definitely a “have your cake and eat it too” solution!
ptg7799847 unoBtrusive JavasCriPt
Before getting into some actual code (about time, right?), there’s one more concept to introduce: unobtrusive JavaScript. Back in the day, JavaScript was often liber-ally interspersed within HTML. For example, a function might be called when a link is clicked:
<a href=”javascript:createWindow();”>A Link</a>
Or, a different function would be called when a form is submitted:
<form action=”somepage.php” method=”post”
p onsubmit=”return validateForm();”>
Both code examples would still work today, but this practice is frowned upon, and rightfully so. For starters, embedding JavaScript within an HTML page makes the whole page of code harder to read and much more difficult to maintain. Having to browse through lines and lines of HTML to edit inline JavaScript is too impractical.
Secondarily, inline JavaScript violates the principle of progressive enhancement in three ways:
J HTML with inline JavaScript is clearly more than just semantic.
J It assumes that the client is capable of handling JavaScript.
J One can’t apply the reliable technique of object detection with embedded JavaScript.
The rule for modern JavaScript, therefore, is simple: Put all JavaScript between script tags or in an external file.
NOTE: avoid using dummy links (links to # or Javascript function calls) in htMl, as those will fail on browsers without Javascript capability.
Key developMent approacheS 43
ptg7799847