This chapter discusses how to use JavaScript to modify and animate positioned blocks of HTML content. First the chapter gives an overview of why you might want to use JavaScript to modify blocks of content, then it discusses the Layer object, which represents a block of content. It shows how to use JavaScript to create new blocks of content, and how to write content dynamically. It discusses how you can make distinct blocks of HTML respond to events. It discusses how each block of content can contain its own localized script, and finishes up by addressing some of the issues involved in animating HTML content.
This chapter does not teach the basics of using the JavaScript language, although it does provide several examples that should help you get started. For more information about JavaScript see:
http://home.netscape.com/eng/mozilla/3.0/handbook/javascript/index.html
/library/documentation/communicator/jsguide/js1_2.htm
The remaining chapters in this part of the book each present a separate complete example of using JavaScript to work with positioned content.
Regardless of how you define your positioned blocks of HTML content, you can write scripts in JavaScript that move them, change their color and size, change their content, make them visible or invisible, and generally modify them in a variety of ways. Furthermore, you can use JavaScript to change the contents of a positioned block or create new ones on-the-fly.
Using JavaScript to work with positioned blocks of HTML content allows you to define animations directly in a web page. For example, you could create an animation that dynamically peels away a series of layers of content to reveal the one underneath. You can make blocks of content move across, over, and under other blocks of content. You can make them appear and disappear. You can make them dynamically expand and contract in response to mouse events. You can generally bring your web page alive with animated content.
You can use JavaScript to modify positioned blocks of HTML content regarless of how the blocks are defined. You can manipulate positioned blocks of HTML content with JavaScript, even if they are defined as styles.
Regardless of how you define a positioned block of HTML content, it can be treated as a modifiable object in JavaScript.
For each layer in an HTML page (whether it is defined with the <LAYER>
tag or as a style whose position
property is either absolute
or relative
) there is a corresponding JavaScript layer
object. You can write JavaScript scripts that modify layers either by directly accessing and modifying property values on the layer objects, or by calling methods on the layer
objects.
Each document object has a layers
property that contains an array of all the top-level layers in the document. Each layer in turn has a document
property.
This document
property has a layers
array that contains all the top-level layers inside this layer. The document of a layer also has all the usual properties of a document object, such as the images
property, which is an array of all the images in the layer, as well as properties that are arrays for all the applets, embeds, links, and named anchors in that layer.
There are several ways you can access a layer from JavaScript. If you know the layer's id (or name) you can access it in the following ways:
document
.layername
For example, the following expression returns the layer named "flowerlayer"
.
document.flowerlayer
document
.layers
[layername]
For example, the following expression returns the layer named "flowerlayer"
.
document.layers["flowerlayer"]
If you know the index for the layer you can access it as follows:
document
.layers
[index]
Note that the first layer has an index of 0, the second layer has an index of 1, and so on. The following expression returns the fourth layer in the document.
document.layers[3]
When accessed by integer index, array elements appear in z-order from back to front, where zero is the bottom-most layer and higher layers are indexed by consecutive integers. The index of a layer is not the same as its zIndex
property, as the latter does not necessarily enumerate layers with consecutive integers. Also, adjacent layers can have the same zIndex
property values, but two layers can never occupy the same index in the array.
You can find the number of layers in a
document or another layer array by obtaining its length
property. For example, the following expression returns the number of top level layers in the document:
document.layers.length
The following expression returns the number of layers nested at the top level inside the layer named "houses"
.
document.layers["houses"].document.layers.length
As with any JavaScript object, you can access the properties of a layer object using the following syntax:
layerObject.propertyName
where layerObject is an expression that evaluates to a layer object, and propertyName is the name of the property to be accessed. For example, the following expression returns the value of the visibility
property of the layer named "flowerlayer"
:
document.flowerlayer.visibility;
The following expression sets the left
property of the layer named "flowerlayer"
to 300 pixels.
document.flowerlayer.left=300;
The following table lists all the properties that you can use to access or modify a layer in JavaScript. Notice that there is only one set of property names. No matter whether a layer was created with the <LAYER>
tag or was defined as a style, you can use the property names listed in the following table to access it or modify it after it has been created.
These property names are case-sensitive.
There are several methods that you can use on a layer
object to modify a layer. As with any JavaScript object, you can invoke a method on a layer
object using the following syntax:
layerObject.methodName(args)
where layerObject is an expression that evaluates to a layer object, methodName is the method to be invoked, and args are the arguments to the method.
For example, the following expression invokes the method moveBy()
on the layer named flowerlayer
, to move the layer 10 pixels to the right and 10 pixels down from its current position.
document.flowerlayer.moveBy(10, 10);
The following table lists all the methods that you can use to access or modify a layer in JavaScript. You will notice that there is only one set of method names. It does not matter whether a layer was created with the <LAYER>
tag or was defined as a style, you can use the methods listed in the following table to access it or modify it after it has been created.
These method names are case-sensitive
You can use JavaScript to create new layer
objects by calling the new
operator on a Layer
object, for example:
bluelayer = document.bluelayer;
newbluelayer = new Layer(300, bluelayer);
The first argument is the width of the new layer, and the second argument, which is optional, is its parent layer. The parent can also be a window, in which case the new layer is created as a top-level layer within the corresponding window. If you do not supply a parent layer, the new layer will be a top-level layer in the current document.
After creating a new layer, you can set its source either by setting a value for its src
property, or by calling the load
method. Alternatively, you can open the layer's document and write to it (as discussed in the next section.)
There are a few important things to know about creating layers and modifying their contents dynamically. You can create a new layer
object by using the new
operator only after the page has completely finished loading. You cannot open a layer's document and write to it until the page has finished loading. You can have only one layer open for writing at a time.
While initially defining a layer, you can write to the layer's document using the document's write
method.
<LAYER ID="layer1" BGcolor="green">
<HR>
<H1>First Heading</H1>
<SCRIPT>
document.write("<P>Here is some content<P>")
</SCRIPT>
<HR>
</LAYER>
After a layer has been initially created and the page has fully finished loading, you can modify the contents of the layer by using the write
() method of the layer's document. If you use the write()
method to write content to a layer after the layer has been created, the original content of the layer is wiped out, and replaced by the new content.
After writing to a layer's document, you need to close the document.
For example:
<LAYER ID="layer1" BGCOLOR="blue">
<HR>
<H1>First Heading</H1>
<P>Here is the original content<P>
<HR>
</LAYER>
</BODY>
</HTML>
<SCRIPT>
function changeLayerContent() {
document.layer1.document.write("<HR><P>New content.</P><HR>");
document.layer1.document.close();
}
</SCRIPT>
<FORM NAME="form">
<INPUT TYPE=button VALUE="CHANGE CONTENT"
ONCLICK='changeLayerContent();return false;'>
</FORM>
For a further example of writing to a layer, see Chapter 12, "Expanding Colored Squares Example."
Each layer can be thought of as a separate document. It has the same event-handling capabilities as a top-level window. You can capture events for a layer.
For an overview of event handling, see the section "Scripting Event Handlers" in the JavaScript guide for in JavaScript. The following link takes you to the JavaScript guide:
http://home.netscape.com/eng/mozilla/3.0/handbook/javascript/index.html
When defining a layer with the The The The The Just as in the case of a document, if you want to define the mouse click response for a layer, you must capture If an event occurs in a place where multiple layers overlap, the top-most layer gets the event, even if it is transparent. However, if a layer is hidden, it does not get events. For an example of capturing events for a layer, see Chapter 13, "Changing Wrapping Width Example."<LAYER>
tag, you can also supply the following attributes that specify event handlers:onMouseOver
onMouseOut
onLoad
onFocus
onBlur
onMouseOver
event handler is invoked when the mouse cursor moves into a layer.onMouseOut
event handler is invoked when the mouse cursor moves out of the area of a layer.onLoad
event handler gets invoked when a layer is loaded, that is, the document that ultimately contains the layer is displayed. This is true regardless of whether a layer is visible or not. onFocus
handler is invoked when the layer gets keyboard focus, and the onBlur
handler is invoked when the layer loses keyboard focus. onMouseDown
and onMouseUp
events at the level of the layer and process them as you want.
You can use the <SCRIPT>
and </SCRIPT>
tags within blocks of positioned content. The functions defined in the script will be scoped to the block that contains them, and they cannot be used outside that block.
This functionality is handy, for example, for defining event handlers for a layer.
<LAYER ID="layer1" BGCOLOR="red"
onMouseOver='changeColor("blue");'
onMouseOut='changeColor("red");'>
<P>Layer content...</P>
<SCRIPT>
function changeColor(newcol) {
bgColor=newcol; // Modifies the layer object's bgColor property
return false;
}
</SCRIPT>
</LAYER>
<DIV STYLE="position:absolute; layer-background-color:red;
width:200px; height:100px">
<P>Layer content...</P>
<SCRIPT>
function onMouseOver() {changeColor("blue");}
function onMouseOut() {changeColor("red");}
function changeColor(newcol) {
bgColor=newcol;
return false;
}
</SCRIPT>
</DIV>
When the mouse moves into the layer, the layer turns blue. When the mouse moves out of the layer, it turns red. To see the example in action, select:
chgcolor.htm
You can use JavaScript to modify layers to produce the effects of animation. Frequently, animation revolves around repeating actions over and over again, particularly for looping animations. You can use the JavaScript function setInterval()
function to repeatedly call a function at a given interval.
For example, the following statement calls the keepExpanding()
function every 25 milliseconds, with arguments of 20, 30, 40 and 50.
setInterval(keepExpanding, 25, 20, 30, 40, 50);
JavaScript also provides the setTimeout()
function, which calls another function after a given amount of time.
The setTimeOut()
function has two different forms:
setTimeout("code to be executed", delay)
setTimeout(function, delay, args...)
For example, to invoke doItAgain("Sam", "piano")
after 3 milliseconds, you can use either of the following statements:
setTimeout("doItAgain('Sam', 'piano')", 3)
setTimeout(doItAgain, 3, "Sam", "piano");
The setTimeout()
function is useful for conditionally re-invoking a function, whereas the setInterval()
function is useful for kicking off the repeated, unconditional invocation of a function.
The following function uses setTimeout()
to keep making the clipping area of a layer 5 pixels wider and 5 pixels higher until the layer is 450 pixels wide.
function expand(layer)
{
if (layer.clip.right < 450) {
layer.resizeBy(5, 5);
setTimeout(expand, 5, layer);
}
return false;
}
You can achieve many interesting animations by changing the source of an image in conjunction with moving the image. To move an image, you can change the position of the layer that contains the image. To change the source of the image, you can assign a new value to the src
property of the image
object.
If the source of the image is changed too quickly or too often, the actual image may not download across the net quickly enough to keep up with the animation. Therefore if you have a script that changes the source of an image in a moving layer, it is best to make sure that the image has fully loaded before you try to do anything with it.
When a document has completely finished loading, it invokes its onLoad
handler if it has one. You could define an onLoad
handler for the BODY
element of a document that initiates any animations in the document. The onLoad
handler for a BODY
element may be invoked before all frames in all animated GIF images have finished loading, but it will not be invoked until at least one frame of every animated GIF image has finished loading.
Layers can also have onLoad
handlers. However, if a layer contains images, the images may load asynchronously from the rest of the layer's content, and the layer may think it has finished loading and thus fire its onLoad
handler (if it has one) before all its images have finished loading.
Images can have onLoad
handlers also. However, if the image is an animated GIF, its onLoad
handler is invoked every time a frame in the image finishes loading. Therefore if your image is an animated GIF, it is better to define an onLoad
handler that initiates any animations that use that image in the BODY
element rather than directly on the image.However, it the image is a static GIF or JPEG, by all means define the onLoad
handler directly on the image.
Chapter 11, "Swimming Fish Example," discusses an example, Positioning and Moving the Fish and Poles, that has a layer containing a fish that swims back and forth. The fish starts swimming when someone clicks on a button. To ensure that nobody can click the button before the fish image has finished loading, the layer containing the button is initially hidden. When the document has finished loading, its onLoad
handler makes the form layer visible.
One way to reduce the time required to start an animation is to ensure that the images used in the animation are downloaded to the browser's cache before the animation starts. This approach is known as prefetching the images.
You can prefetch an image by embedding it in a layer. When a layer loads, it loads all its content, including all images, regardless of whether the layer is visible or not. If a page has a hidden layer that contains all the images needed in the animation then when the page opens, the source for the images is downloaded into the browser's cache, even though they are not visible.
Chapter 11, "Swimming Fish Example," discusses an example, Changing the Stacking Order of Fish and Poles, that illustrates the use of a hidden layer to contain images that are not needed when the page opens but are used in the course of animating the contents of the page.
By default, when a page opens, it shows a placeholder icon for every image in the page that has not finished loading. Animation sequences may sometimes require multiple images. While the images are loading, the user could see lots of placeholder icons that you would prefer they did not see.
A new attribute has been introduced for the IMG
tag to allow you to suppress the display of placeholder icons.
The SUPPRESS
attribute for the IMG
tag can be set to either true or false. The default value is false
. If SUPPRESS
is set to true
, neither the place-holder icon or frame that appear during image loading will be displayed and tool-tips will be disabled for that image.
If SUPPRESS
is set to false
, the place-holder icon and frame will always be displayed during loading even if the images are transparent images that would not otherwise be displayed. Tool tips will be active.
Last Updated: 08/07/97 15:21:59