Javascript [Electronic resources] : The Definitive Guide (4th Edition) نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Javascript [Electronic resources] : The Definitive Guide (4th Edition) - نسخه متنی

David Flanagan

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید


12.3 Execution of JavaScript Programs


The previous section discussed the mechanics of integrating
JavaScript code into an HTML file. Now we move on to discuss exactly
how that integrated JavaScript code is executed by the JavaScript
interpreter. The following sections explain how different forms of
JavaScript code are executed. While some of this material is fairly
obvious, there are a number of important details that are not so
obvious.


12.3.1 Scripts




JavaScript
statements that appear between <script> and
</script> tags are executed in order of
appearance; when more than one script appears in a file, the scripts
are executed in the order in which they appear. If a script calls
document.write( ), any text passed to that method
is inserted into the document immediately after the closing
</script> tag and is parsed by the HTML
parser when the script finishes running. The same rules apply to
scripts included from separate files with the src
attribute.

The detail that is not so obvious, but
is nevertheless important to remember, is that execution of scripts
occurs as part of the web browser's HTML parsing process. Thus,
if a script appears in the <head> section
of an HTML document, none of the
<body> section of the document has been defined
yet. This means that the JavaScript objects that represent the
contents of the document body, such as Form and Link, have not been
created yet and cannot be manipulated by that code.

Your scripts should not attempt to manipulate objects that have not
yet been created. For example, you can't write a script that
manipulates the contents of an HTML form if the script appears before
the form in the HTML file. Some other, similar rules apply on a
case-by-case basis. For example, there are properties of the Document
object that may be set only from a script in the
<head> section of an HTML document, before
the browser has begun to parse the document content in the
<body> section. Any special rules of this
sort are documented in the reference page for the affected object or
property in the client-side reference.

Since scripts are executed while the HTML document that contains them
is being parsed and displayed, they should not take too long to run.
Because scripts can create dynamic document content with
document.write( ), the HTML parser must stop
parsing the document whenever the JavaScript interpreter is running a
script. An HTML document cannot be fully displayed until all the
scripts it contains have finished executing. If a script performs
some computationally intensive task that takes a long time to run,
the user may become frustrated waiting for the document to be
displayed. Thus, if you need to perform a lot of computation with
JavaScript, you should define a function to do the computation and
invoke that function from an event handler when the user requests it,
rather than doing the computation when the document is first loaded.


As I noted
earlier, scripts that use the src attribute to
read in external JavaScript files are executed just like scripts that
include their code directly in the file. What this means is that the
HTML parser and the JavaScript interpreter must both stop and wait
for the external JavaScript file to be downloaded. (Unlike embedded
images, scripts cannot be downloaded in the background while the HTML
parser continues to run.) Downloading an external file of JavaScript
code, even over a relatively fast modem connection, can cause
noticeable delays in the loading and execution of a web page. Of
course, once the JavaScript code is cached locally, this problem
effectively disappears.


12.3.2 Functions




Remember
that defining a function is not the same as executing it. It is
perfectly safe to define a function that manipulates objects that
have not yet been created. Just take care that the function is not
executed or invoked until the necessary variables, objects, and so on
all exist. I said earlier that you can't write a script to
manipulate an HTML form if the script appears before the form in the
HTML file. You can, however, write a script that defines a function
to manipulate the form, regardless of the relative locations of the
script and form. In fact, this is a common practice. Many JavaScript
programs start off with a script in the
<head> of the document that does nothing
more than define functions that are used in the
<body> of the HTML file.

It is also common to write JavaScript programs that use scripts
simply to define functions that are later invoked through event
handlers. As we'll see in the next section, you must take care
in this case to ensure two things: that all functions are defined
before any event handler attempts to invoke them, and that event
handlers and the functions they invoke do not attempt to use objects
that have not yet been defined.


12.3.3 Event Handlers


Defining an

event handler as the value of an
onclick or another HTML attribute is much like
defining a JavaScript function: the code is not immediately executed.
Event-handler execution is asynchronous. Since events generally occur
when the user interacts with HTML objects, there is no way to predict
when an event handler will be invoked.

Event handlers share an important restriction with scripts: they
should not take a long time to execute. As we've seen, scripts
should run quickly because the HTML parser cannot continue parsing
until the script finishes executing. Event handlers, on the other
hand, should not take long to run because the user cannot interact
with your program until the program has finished handling the event.
If an event handler performs some time-consuming operation, it may
appear to the user that the program has hung, frozen, or crashed.

If for some reason you must perform a long operation in an event
handler, be sure that the user has explicitly requested that
operation, and then notify him that there will be a wait. As
we'll see in Chapter 13, you can notify the
user by posting an alert( ) dialog box or
displaying text in the browser's status line. Also, if your
program requires a lot of background processing, you can schedule a
function to be called repeatedly during idle time with the
setTimeout( )

method.

It is important to understand that event handlers may be invoked
before a web page is fully loaded and parsed. This is easier to
understand if you imagine a slow network connection -- even a
half-loaded document may display hypertext links and form elements
that the user can interact with, thereby causing event handlers to be
invoked before the second half of the document is
loaded.

The fact that event handlers can be invoked before a document is
fully loaded has two important implications. First, if your event
handler
invokes a
function, you must be sure that the function is already defined
before the handler calls it. One way to guarantee this is to define
all your functions in the
<head> section of an HTML document. This section
of a document is always completely parsed (and any functions in it
defined) before the <body> section of the
document is parsed. Since all objects that define event handlers must
themselves be defined in the
<body>
section, functions in the
<head> section are guaranteed to be defined
before any event handlers are invoked.

The second implication is that you must be sure that your event
handler does not attempt to manipulate HTML objects that have not yet
been parsed and created. An event handler can always safely
manipulate its own object, of course, and also any objects that are
defined before it in the HTML file. One strategy is simply to define
your web page's user interface in such a way that event
handlers refer only to previously defined objects. For example, if
you define a form that uses event handlers only on the

Submit and

Reset buttons, you just need to place these
buttons at the bottom of the form (which is where good user-interface
style says they should go anyway).

In more complex programs, you may not be able to ensure that event
handlers manipulate only objects defined before them, so you need to
take extra care with these programs. If an event handler manipulates
only objects defined within the same form, it is pretty unlikely that
you'll ever have problems. When you manipulate objects in other
forms or other frames, however, this starts to be a real concern. One
technique is to test for the existence of the object you want to
manipulate before you manipulate it. You
can do this simply by
comparing it (and any parent
objects) to null. For
example:

<script>
function set_name_other_frame(name)
{
if (parent.frames[1] == null) return; // Other frame not yet defined
if (!parent.frames[1].document) return; // Document not yet loaded in it
if (!parent.frames[1].document.myform) return; // Form not yet defined
if (!parent.frames[1].document.myform.name) return; // Field not yet defined
parent.frames[1].document.myform.name.value = name;
}
</script>
<input type="text" name="lastname"
onchange="set_name_other_frame(this.value)";
>

In JavaScript 1.5 and later, you can omit the existence tests in the
previous code if you instead use the try/catch
statement to catch the exception that will be thrown if the function
is invoked before the document is fully loaded.

Another technique that an event handler can use to ensure that all
required objects are defined involves the onload event
handler. This event handler is defined in the
<body> or
<frameset> tag of an HTML file and is
invoked when the document or frameset is fully loaded. If you set a
flag within the onload event handler, other event
handlers can test this flag to see if they can safely run, with the
knowledge that the document is fully loaded and all objects it
contains are defined. For example:

<body onload="window.fullyLoaded = true;">
<form>
<input type="button" value="Do It!"
onclick="if (window.fullyLoaded) doit( );">
</form>
</body>


12.3.3.1 onload and onunload event handlers

The
onload event handler and its partner
onunload are worth a special mention in the
context of the execution order of JavaScript programs. Both of these
event handlers are defined in the <body> or
<frameset> tag of an HTML file. (No HTML
file can legally contain both of these tags.) The
onload handler is executed when the document or
frameset is fully loaded, which means that all images have been
downloaded and displayed, all subframes have loaded, any Java applets
have started running, and so on. Be aware that when you are working
with multiple frames, there is no guarantee of the order in which the
onload event handler is invoked for the various
frames, except that the handler for the parent frame is invoked after
the handlers of all its child frames.

The onunload handler is executed just before the
page is unloaded, which occurs when the browser is about to move on
to a new page. You can use it to undo the effects of your
onload handler or other scripts in your web page.
For example, if your web page opens up a secondary browser window,
the onunload handler provides an opportunity to
close that window when the user moves on to some other web page. The
onunload handler should not run any kind of
time-consuming operation, nor should it pop up a dialog box. It
exists simply to perform a quick cleanup operation; running it should
not slow down or impede the user's transition to a new page.


12.3.4 JavaScript URLs



JavaScript code in a
javascript: URL is
not executed when the document containing the URL is loaded. It is
not interpreted until the browser tries to load the document to which
the URL refers. This may be when a user types in a JavaScript URL or,
more likely, when a user follows a link, clicks on a client-side
image map, or submits a form. javascript: URLs are
often used as an alternative to event handlers, and as with event
handlers, the code in those URLs can be executed before a document is
fully loaded. Thus, you must take the same precautions with
javascript: URLs that you take with event handlers
to ensure that they do not attempt to reference objects (or
functions) that are not yet defined.


12.3.5 Window and Variable Lifetime



A final topic in our investigation

of how client-side JavaScript
programs run is the issue of variable lifetime. We've seen that
the Window object is the global object for client-side JavaScript and
that all global variables are properties of the Window object. What
happens to Window objects and the variables they contain when the web
browser moves from one web page to another?

Whenever a new document is loaded into a window or a frame, the
Window object for that window or frame is restored to its default
state: any properties and functions defined by a script in the
previous document are deleted, and any of the standard system
properties that may have been altered or overwritten are restored.
Every document begins with a "clean slate." Your scripts
can rely on this -- they will not inherit a corrupted environment
from the previous document. Any variables and functions your scripts
define persist only until the document is replaced with a new one.

The clean slate we're discussing here is the Window object that
represents the window or frame into which the document is loaded. As
we've discussed, this Window object is the global object for
JavaScript code in that window or frame. However, if you're
working with multiple frames or multiple windows, a script in one
window may refer to the Window objects that represent other windows
or frames. So in addition to considering the persistence of variables
and functions defined in Window objects, we must also consider the
persistence of the Window object itself.

A Window object that represents a top-level browser window exists as long as
that window exists. A reference to the Window object remains valid
regardless of how many web pages the window loads and unloads. The
Window object is valid as long as the top-level window is
open.[4]

[4] A Window object may not actually be destroyed
when its window is closed. If there are still references to the
Window object from other windows, the object is not garbage
collected. However, a reference to a window that has been closed is
of very little practical use.

A Window object that represents a
frame remains valid as long as that frame
remains within the frame or window that contains it. For example, if
frame A contains a script that has a reference to the Window object
for frame B, and a new document is loaded into frame B, frame
A's reference to the Window object remains valid. Any variables
or functions defined in frame B's Window object will be deleted
when the new document is loaded, but the Window object itself remains
valid (until the containing frame or window loads a new document and
overwrites both frame A and frame B).

This means that Window objects, whether they represent top-level
windows or frames, are quite persistent. The lifetime of a Window
object may be longer than that of the web pages it contains and
displays and longer than the lifetime of the scripts contained in the
web

pages
it displays.

/ 844