Section 13.1. The Web Browser Environment


13.1. The Web Browser Environment

To understand client-side JavaScript, you must understand the programming environment provided by a web browser. The following sections introduce three important features of that programming environment:

  • The Window object that serves as the global object and global execution context for client-side JavaScript code

  • The client-side object hierarchy and the Document Object Model that forms a part of it

  • The event-driven programming model

These sections are followed by a discussion of the proper role of JavaScript in web application development.

13.1.1. The Window as Global Execution Context

The primary task of a web browser is to display HTML documents in a window. In client-side JavaScript, the Document object represents an HTML document, and the Window object represents the browser window (or frame) that displays the document. While the Document and Window objects are both important to client-side JavaScript, the Window object is more important for one substantial reason: the Window object is the global object in client-side programming.

Recall from Chapter 4 that in every implementation of JavaScript there is always a global object at the head of the scope chain; the properties of this global object are global variables. In client-side JavaScript, the Window object is the global object. The Window object defines a number of properties and methods that allow you to manipulate the web browser window. It also defines properties that refer to other important objects, such as the document property for the Document object. Finally, the Window object has two self-referential properties, window and self. You can use either global variable to refer directly to the Window object.

Since the Window object is the global object in client-side JavaScript, all global variables are defined as properties of the window. For example, the following two lines of code perform essentially the same function:

 var answer = 42;     // Declare and initialize a global variable window.answer = 42;  // Create a new property of the Window object 

The Window object represents a web browser window (or a frame within a window; in client-side JavaScript, top-level windows and frames are essentially equivalent). It is possible to write applications that use multiple windows (or frames). Each window involved in an application has a unique Window object and defines a unique execution context for client-side JavaScript code. In other words, a global variable declared by JavaScript code in one window is not a global variable within a second window. However, JavaScript code in the second window can access a global variable of the first window, subject to certain security restrictions. These issues are considered in detail in Chapter 14.

13.1.2. The Client-Side Object Hierarchy and the DOM

The Window object is the key object in client-side JavaScript. All other client-side objects are accessed via this object. For example, every Window object defines a document property that refers to the Document object associated with the window and a location property that refers to the Location object associated with the window. When a web browser displays a framed document, the frames[] array of the top-level Window object contains references to the Window objects that represent the frames. Thus, in client-side JavaScript, the expression document refers to the Document object of the current window; the expression frames[1].document refers to the Document object of the second frame of the current window.

The Document object (and other client-side JavaScript objects) also have properties that refer to other objects. For example, every Document object has a forms[] array containing Form objects that represent any HTML forms appearing in the document. To refer to one of these forms, you might write:

 window.document.forms[0] 

To continue with the same example, each Form object has an elements[] array containing objects that represent the various HTML form elements (input fields, buttons, etc.) that appear within the form. In extreme cases, you can write code that refers to an object at the end of a whole chain of objects, ending up with expressions as complex as this one:

 parent.frames[0].document.forms[0].elements[3].options[2].text 

As shown earlier, the Window object is the global object at the head of the scope chain, and all client-side objects in JavaScript are accessible as properties of other objects. This means that there is a hierarchy of JavaScript objects, with the Window object at its root. Figure 13-1 shows this hierarchy.

Figure 13-1. The client-side object hierarchy and Level 0 DOM


Note that Figure 13-1 shows just the object properties that refer to other objects. Most of the objects shown in the diagram have methods and properties other than those shown.

Many of the objects pictured in Figure 13-1 descend from the Document object. This subtree of the larger client-side object hierarchy is known as the document object model (DOM), which is interesting because it has been the focus of a standardization effort. Figure 13-1 illustrates the Document objects that have become de facto standards because they are consistently implemented by all major browsers. Collectively, they are known as the Level 0 DOM because they form a base level of document functionality that JavaScript programmers can rely on in all browsers. These basic Document objects are covered in Chapter 15, which also explains a more advanced document object model that has been standardized by the W3C. HTML forms are part of the DOM but are specialized enough that they are covered in their own chapter, Chapter 18.

13.1.3. The Event-Driven Programming Model

In the early days of computing, computer programs often ran in batch mode; they read in a batch of data, did some computation on that data, and then wrote out the results. Later, with time-sharing and text-based terminals, limited kinds of interactivity became possible; the program could ask the user for input, and the user could type in data. The computer then processed the data and displayed the results onscreen.

Nowadays, with graphical displays and pointing devices such as mice, the situation is different. Programs are generally event-driven; they respond to asynchronous user input in the form of mouse clicks and keystrokes in a way that depends on the position of the mouse pointer. A web browser is just such a graphical environment. An HTML document contains an embedded graphical user interface (GUI), so client-side JavaScript uses the event-driven programming model.

It is perfectly possible to write a static JavaScript program that does not accept user input and does exactly the same thing every time it is run. Sometimes this sort of program is useful. More often, however, you'll want to write dynamic programs that interact with the user. To do this, you must be able to respond to user input.

In client-side JavaScript, the web browser notifies programs of user input by generating events. There are various types of events, such as keystroke events, mouse motion events, and so on. When an event occurs, the web browser attempts to invoke an appropriate event handler function to respond to the event. Thus, to write dynamic, interactive client-side JavaScript programs, you must define appropriate event handlers and register them with the system, so that the browser can invoke them at appropriate times.

If you are not already accustomed to the event-driven programming model, it can take a little getting used to. In the old model, you wrote a single, monolithic block of code that followed some well-defined flow of control and ran to completion from beginning to end. Event-driven programming stands this model on its head. In event-driven programming, you write a number of independent (but mutually interacting) event handlers. You do not invoke these handlers directly but allow the system to invoke them at the appropriate times. Since they are triggered by the user's input, the handlers are invoked at unpredictable, asynchronous times. Much of the time, your program is not running at all but merely sitting, waiting for the system to invoke one of its event handlers.

The sections that follow explain how JavaScript code is embedded within HTML files. It shows how to define both static blocks of code that run synchronously from start to finish and event handlers that are invoked asynchronously by the system. Events and event handling are discussed again in Chapter 15, and then events are covered in detail in Chapter 17.

13.1.4. The Role of JavaScript on the Web

The introduction to this chapter included a list of the web browser capabilities that can be scripted with client-side JavaScript. Note, however, that listing what JavaScript can be used for is not the same as explaining what JavaScript ought to be used for. This section attempts to explain the proper role of JavaScript in web application development.

Web browsers display HTML-structured text styled with CSS stylesheets. HTML defines the content, and CSS supplies the presentation. Properly used, JavaScript adds behavior to the content and its presentation. The role of JavaScript is to enhance a user's browsing experience, making it easier to obtain or transmit information. The user's experience should not be dependent on JavaScript, but JavaScript can serve to facilitate that experience. JavaScript can do this in any number of ways. Here are some examples:

  • Creating visual effects such as image rollovers that subtly guide a user and help with page navigation

  • Sorting the columns of a table to make it easier for a user to find what he needs

  • Hiding certain content and revealing details selectively as the user "drills down" into that content

  • Streamlining the browsing experience by communicating directly with a web server so that new information can be displayed without requiring a complete page reload

13.1.5. Unobtrusive JavaScript

A new client-side programming paradigm known as unobtrusive JavaScript has been gaining currency within the web development community. As its name implies, this paradigm holds that JavaScript should not draw attention to itself; it should not obtrude.[*] It should not obtrude on users viewing a web page, on content authors creating HTML markup, or on web designers creating HTML templates or CSS stylesheets.

[*] "Obtrude" is an obscure synonym for "intrude." The American Heritage dictionary cites: "To impose... on others with undue insistence or without invitation."

There is no specific formula for writing unobtrusive JavaScript code. However, a number of helpful practices, discussed elsewhere in this book, will put you on the right track.

The first goal of unobtrusive JavaScript is to keep JavaScript code separate from HTML markup. This keeps content separate from behavior in the same way that putting CSS in external stylesheets keeps content separate from presentation. To achieve this goal, you put all your JavaScript code in external files and include those files into your HTML pages with <script src=> tags (see Section 13.2.2. for details). If you are strict about the separation of content and behavior, you won't even include JavaScript code in the event-handler attributes of your HTML files. Instead, you will write JavaScript code (in an external file) that registers event handlers on the HTML elements that need them (Chapter 17 describes how to do this).

As a corollary to this goal, you should strive to make your external files of JavaScript code as modular as possible using techniques described in Chapter 10. This allows you to include multiple independent modules of code into the same web page without worrying about the variables and functions of one module overwriting the variables and functions of another.

The second goal of unobtrusive JavaScript is that it must degrade gracefully. Your scripts should be conceived and designed as enhancements to HTML content, but that content should still be available without your JavaScript code (as will happen, for example, when a user disables JavaScript in her browser). An important technique for graceful degradation is called feature testing: before taking any actions, your JavaScript modules should first ensure that the client-side features they require are available in the browser in which the code is running. Feature testing is a compatibility technique described in more detail in Section 13.6.3.

A third goal of unobtrusive JavaScript is that it must not degrade the accessibility of an HTML page (and ideally it should enhance accessibility). If the inclusion of JavaScript code reduces the accessibility of web pages, that JavaScript code has obtruded on the disabled users who rely on accessible web pages. JavaScript accessibility is described in more detail in Section 13.7.

Other formulations of unobtrusive JavaScript may include other goals in addition to the three described here. One primary source from which to learn more about unobtrusive scripting is "The JavaScript Manifesto," published by the DOM Scripting Task Force at http://domscripting.webstandards.org/?page_id=2.




JavaScript. The Definitive Guide
JavaScript: The Definitive Guide
ISBN: 0596101996
EAN: 2147483647
Year: 2004
Pages: 767

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