Section C. Preparing the page


C. Preparing the page

After you've made decisions on the HTML and CSS structure and the hooks you're going to use, it's time to write the initialization function that prepares the page for the script to come.

We'll discuss the mechanics of initialization in 4E. Here, I'd like to concentrate on the purposes of the initialization script, and the high-level decisions you make while writing it.

In this section we'll go through the most important actions the example scripts take during the initialization phase. The emphasis will be on the purpose of these actions, and not on the technical nuts and bolts (most of which are treated in later chapters).

Setting event handlers

The most important action the initialization function takes is registering event handlers. As far as the user is concerned, the script starts when he takes action and the page responds. But which action should he take?

Usually, the correct event is obvious. Form Validation clearly needs the submit event: the script starts up when the user submits the form. Dropdown Menu clearly needs the mouseover and mouseout events: the menus should become visible when the user moves the mouse over them, and be hidden when the mouse moves out again.

Nonetheless you could face some tricky decisions, too. What if a Dropdown Menu user doesn't use a mouse? Which events does Site Survey use? Exactly when do we read out the length of the text area's content in Textarea Maxlength?

Usable Forms is a difficult case. The most logical event would be the change event: The script fires whenever the user changes a form field. Unfortunately there are technical problems that preclude its use.

The most important thing you must do in this phase is clearly picture what the user should do to start up the script. Once you've made that decision you can go through the available events (see 7B) and decide on the best, or, in some cases, the least confusing one to use. We'll study the event handlers of all example scripts in detail in 7G.

Determining visitor status

Occasionally you need to determine exactly what's going to happen when a visitor enters your page. Site Survey is the prime example here.

First, the script determines the survey status. Is it still active, i.e., does the current day fall between the start and end dates of the survey? If not, the script ends.

When a new user visits the site, a script draws a random number that decides whether or not the user is selected for the survey, and stores this information in a cookie. If she isn't selected, she should not be bothered with the survey for at least another day; technically that's done by setting the cookie to expire in a day's time. If she is selected, the survey popup should appear.

When a user returns to the site, the script discovers the cookie from the previous visit and does nothing. The client and I decided that a user who has already gone through the selection process is never led to the survey.

This is not especially difficult, but it has to be taken care of during the initialization. We'll study this example of cookie use in 6G.

Setting up access

Sometimes a script needs access to a certain resource. Edit Style Sheet, for example, needs access to the style sheet it's going to edit.

Therefore the initialization function starts by finding out whether the user's browser supports the editing of entire style sheets, and then creates a variable which points to the correct style sheet. We'll discuss this in 9D.

Generating content

Sometimes it's necessary to modify the HTML document. As we saw in 2E, it may be useful to generate HTML elements such as links or buttons in JavaScript when they are useless without JavaScript support.

Take Sandwich Picker. A lot has to be prepared before the user can start picking sandwiches. Every sandwich <tr> needs an Order and a Trash button, and since they make no sense without JavaScript support I use the W3C DOM to add them. The script first creates template nodes, and when the initialization script goes through all <tr>s it inserts clones of these nodes into the first <td> that also holds the form field.

We'll discuss the technical details in 8E, but the point here is that the initialization script is the only correct place to create the buttons, since they should be available at the moment the user starts interacting with the page.

Defining relations

Occasionally, I define relations between one HTML element and another if an event on the first element should trigger changes in the other element. Thus I don't have to search for the other element when the event takes place: this bit of data has already been defined.

Textarea Maxlength is a good example. When the user enters text in the text area, a counter should appear that shows the number of characters. If the user exceeds the maximum length, the counter should become red and bold. This counter is a <span> element.

In order to keep the script simple, I want to define the relation between a textarea and its counter element during initialization:

[Textarea Maxlength, lines 7-10]

// textareas[i] is the textarea currently being initialized var counterClone = counter.cloneNode(true); counterClone.innerHTML = <span>0</span>/'+ textareas[i].getAttribute('maxlength'); textareas[i].parentNode.insertBefore(counterClone, textareas[i].nextSibling); textareas[i].relatedElement = counterClone.getElementsByTagName('span')[0]; 


I first create a new counter by cloning an element and adding text and a <span> tag to it. Then I insert it just after the textarea. (We'll discuss insertBefore() and cloneNode() in 8D and 8E, respectively.)

Finally I give the textarea a relatedElement property that points to the <span> that should be updated whenever the user types something. It is now very easy to access the <span> from the event-handling function on the textarea:

[Textarea Maxlength, lines 17-25]

// 'this' is the textarea the user has entered characters in function checkMaxLength() { var maxLength = this.getAttribute('maxlength'); var currentLength = this.value.length; if (currentLength > maxLength)        this.relatedElement.className = 'toomuch'; else        this.relatedElement.className = ''; this.relatedElement.firstChild.nodeValue = currentLength; } 


First the script finds out if the maximum length has been exceeded. If so, it sets the class of the relatedElement (the <span>) to 'toomuch'. Then it sets the content of the <span> to the current length of the textarea. In this way, checkMaxLength() has easy access to the <span> it should change.

Dropdown Menus uses the same trick, by the way. We'll study it in 7H.

Modifying document structure

The initialization function can also be used for large-scale modification of the document. For example, in Usable Forms, the script should remove all <tr>s that have a rel attribute. It should also make sure that they can be easily retrieved when the user clicks on a form field.

My solution creates an object, hiddenFormFieldPointers, that stores pointers to all <tr>s that are removed. These pointers are indexed by the value of the rel attribute. When the user clicks on a field that has rel="othercountry", the script re-inserts the <tr>s that hiddenFormFieldPointers["othercountry"] points to.

Well discuss the technical nuts and bolts in 8K. Just note that such a setup requires careful planning as well as an initialization script that creates the necessary structures (such as hiddenFormFieldPointers) before anything else happens.



ppk on JavaScript. Modern, Accessible, Unobtrusive JavaScript Explained by Means of Eight Real-World Example Scripts2006
ppk on JavaScript. Modern, Accessible, Unobtrusive JavaScript Explained by Means of Eight Real-World Example Scripts2006
ISBN: N/A
EAN: N/A
Year: 2005
Pages: 116

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net