Dynamic documents notes
Dynamic documents notes
DTML
Introduction
Dynamic XHTML is not a new markup language. It is a collection of technolo
gies that allows dynamic changes to documents described with XHTML. Spe-
cifically, a dynamic XHTML document is one whose tag attributes, tag contents,
or element style properties can be changed after the document has been and is
still being displayed by a browser. Such changes can be made with an embedded
script that accesses the elements of the document as objects in the associated
Document Object Model (DOM) structure.
PositioningElements
Before the browsers that implemented HTML 4.0 appeared, Web site authors had little
control over how HTML elements were arranged in documents. In
many cases, the elements found in the HTML file were simply placed in the
document the way text is placed in a document with a word processor-fill a
row, start a new row, fill it, and so forth. HTML tables provide a framework of
columns for arranging elements, but they lack flexibility and also take a consid-
erable time to display. This lack of powerful and fast element placement control ended when
Cascading Style Sheets-Positioning (CSS-P) was released by
theW3Cin1997.
CSS-P is completely supported by IE7 and FX2. It provides the means not
only to position any element anywhere in the display of a document, but also to
move an element to a new position in the display dynamically, using JavaScript
to change the positioning style properties of the element. These style proper-
ties, which are appropriately named left and top, dictate the distance from
the left and top of some reference point to where the element is to appear.
Another style property, position, interacts with left and top to provide a
higher level of control of placement and movement of elements. The
position property has three possible values: absolute, relative, and
static.
AbsolutePositioning
The absolute value is specified for position when the element is to be
placed at a specific place in the document display without regard to the
positions of other elements. For example, if you want a paragraph of text to
appear 100 pixels from the left edge of the display window and 200 pixels from
the top, you could use the following-
<p style "position: absolute; left: 100px; top: 200px">
</p>
One use of absolute positioning is to superimpose special text over a para-
graph of ordinary text to create an effect similar to a watermark on paper. A
larger italicized font, with space between the letters in a light gray color, could
be used for the special text, allowing both the ordinary text and the special text
to be legible. The following XHTML document provides an example that
implements this approach. In this example, a paragraph of normal text that
describes apples is displayed. Superimposed on this paragraph is the somewhat
subliminal message "APPLES ARE GOOD FOR YOU."
text—
<html>
<head>
<title> Absolute positioning </title>
<style type= "text/css">
Notice that a width property value is included in the style for both the reg-
ular and the special text. This property is used here so we can ensure that the
special text is uniformly embedded in the regular text. Without it, the text
would extend to the right end of the browser display window. And, of course,
the width of the window could vary widely from client to client and even from
minute to minute on the same client because the user can resize the browser
window at any time.
When an element is absolutely positioned inside another positioned ele-
ment (one that has the position property specified), the top and left prop-
erty values are measured from the upper-left corner of the enclosing element
(rather than the upper-left corner of the browser window).
To illustrate nested element placement, we modify the document
absPos.html to place the regular text 100 pixels from the top and 100 pixels
from the left. The special text is nested inside the regular text by using <div> and
<span> tags. The modified document, which is named absPos2.html, follows:
Relative Positioning
An element that has the position property set to relative but does not specify top and left
property values is placed in the document as if the position attribute were not set at all.
However, such an element can be moved later. If the top and left properties are given values,
they displace the element by the specified amount from the position where it would have
been placed (if top and left had not been set). For example, suppose that two buttons are
placed in a document, and the position attribute has its default value, which is static. They
would appear next to each other in a row, assuming the current row had sufficient horizontal
space for them. If position has been set to relative and the second button had its left property
set to 50px, the effect would be to move it 50 pixels farther to the right than it otherwise
would have appeared.
In both the case of an absolutely positioned element inside another element and the case
of a relatively positioned element, negative values of top and left displace the element
upward and to the left, respectively.
Relative positioning can be used for a variety of special effects in element placement. For
example, it can be used to create superscripts and subscripts by placing the values to be raised
or lowered in <span> tags and displacing them from their regular positions. In the following
example, a line of text is set in a normal font style in 24-point size. Embedded in the line is
one word that is set in italic, 48-point, red font. Normally, the bottom of the special word
would align with the bottom of the rest of the line. In this case, we want the special word to
be vertically centered in the line, so its position property is set to relative and its top property
is set to 10 pixels, which lowers it by that amount relative to the surrounding text. The
XHTML document to specify this, which is named relPos.html, follows:
Illustrates relative positioning of elements
Positioning Elements
<html >
<head>
<title> Relative positioning </title>
</head>
<body style="font-family: Times; font-size: 24pt;">
<p>
Apples are <span style ="position: relative; top: 10px;
font-family: Times; font-size: 48pt;
font-style: italic; color: red;">
GOOD </span> for you.
</p>
</body>
</html>
Static Positioning
The default value for the position property is static. A statically positioned element is placed
in the document as if it had the position value of relative. The difference is that a statically
positioned element cannot have its top or left properties initially set or changed later.
Therefore, a statically placed element cannot be displaced from its normal position and
cannot be moved from that position later.
Moving Elements
An XHTML element whose position property is set to either absolute or relative can be
moved. Moving an element is simple: Changing the top or left property values causes the
element to move on the display. If its position is set to absolute, the element moves to the
new values of top and left; if its position is set to relative, it moves from its original position
by distances given by the new values of top and left.
In the following example, an image is absolutely positioned in the display. The document
includes two text boxes labeled x coordinate and y coordinate. The user can enter new values
for the left and top properties of the image in these boxes. When the Move It button is
pressed, the values of the left and top properties of the image are changed to the given values,
and the element is moved to its new position.
A JavaScript function, stored in a separate file, is used to change the values of left and top
in our example. Although it is not necessary in our example, the id of the element to be
moved is sent to the moving function, just to illustrate that the function could be used on any
number of different elements. The values of the two text boxes are also sent to the function as
parameters. The actual parameter values are the DOM addresses of the text boxes, with the
value attribute attached, which provides the complete DOM addresses of the text box values.
Notice that we attach style to the DOM address of the image to be moved because top and left
are style properties. Because the input top and left values from the text boxes are just string
representations of numbers, but the tap and left properties must end with some unit
abbreviation, the event handler catenates "px” to each value before assigning it to the top and
left properties.
<html>
<head>
<titles Moving elements </title>
<Script type="text/javascript" src= "mover.js">
<body>
<form action=””>
<p>
<label>
x-coordinate:
<input type="text" id = "leftcoord" size= “3" />
y coordinate:
<input type="text" id = "topcoord" size="3" />
<input type="button" value = "Move it"
onclick =
"moveIt ('nebula',
document.getElementById('topCoord').value,
document.getElementById('leftCoord').value)" />
</p></form>
<div id = "nebuia" style="position: absolute;
top: 115px; left: 0;">
<img src= “/images/nge604.jpg"
alt = "(Picture of a nebulay" />
</div>
</body>
</html>
// mover.js
function moveIt (movee, newTop, newLeft) {
dom document.getElementById(movee).style;
dom.top= newTop+"px";
dom.left = newLeft +"px";
}
Element Visibility
Document elements can be specified to be visible or hidden with the value of their visibility
property. The two possible values for visibility are, quite naturally, visible and hidden. The
appearance or disappearance of an element can be controlled by the user through a widget.
The following example displays an image and allows the user to toggle (with a button)
causing the image to appear and not appear in the document dis- play. Once again, the event
handler is in a separate file.
<!-- showHide.html
Uses showHide.js
Illustrates visibility control of elements
<html>
<head>
<title> Visibility control </title>
<script type="text/javascript" type=”showHide.js”>
</script>
</head>
<body>
<form action = "">
<div id= "saturn" style="position: relative; visibility: visible;">
<img src = "../images/saturn.jpg" alt="(Picture of Saturn)" />
</div>
<p>
<input type="button" value="Toggle Saturn"
onclick="flipImag()" />
</p>
</form>
</body>
</html>
// showHide.js
// Illustrates visibility control of elements
function flipImag() {
dom=document.getElementById("saturn").style;
// Flip the visibility adjective to whatever it is not now
if (dom.visibility == "visible")
dom.visibility="hidden";
else
dom.visibility = "visible";
}
Changing Colors and Fonts
The background and foreground colors of the document display can be dynamically changed,
as can the font properties of the text.
Changing Colors
Dynamic changes to colors are relatively simple. In the following example, the user is
presented with two text boxes into which color specifications can be typed one for the
document background color and one for the foreground color. The colors can be specified by
any of the three ways that color properties can be given anywhere else. A JavaScript function,
which is called (using the onchange event) whenever one of the text boxes is changed, makes
the change in the document's appropriate color property, backgroundColor or color. The first
of the two parameters to the function specifies whether the new color is for the background or
foreground; the second specifies the new color. The new color is the value property of the
text box that was changed by the user.
In this example, the calls to the handler functions are in the XHTML text box elements. This
situation allows a simple way to reference the element's DOM address. The JavaScript this
variable in this situation is a reference to the object that represents the element in which it is
referenced. A reference to such an object is its DOM address. Therefore, in a text element,
the value of this is the DOM address of the text element. So, in our example, this.value is
used as an actual parameter to the handler function. Because the call is in an input element,
this.value is the DOM address of the value of the input element.
<label>
Background color:
<input type="text" name="background" size =”10” onchange ="setColor("background",
this.value)”>
</label>
<br />
<label>
Foreground color:
</html>
// dynColors.js
}
Changing Fonts
Web users are accustomed to having links in documents change color when the
cursor is placed over them. Any property of a link can be changed by using the
mouse event mouseover to trigger JavaScript event handlers. Thus, the font style and font
size, as well as the color and background color of a link, can changed when the cursor is
placed over the link. The link can be changed be to its original form when an event handler is
triggered with the mouse event. In the following example, the only element is a sentence with
an enbedded link. The foreground color for the document is the default black. The is
presented in blue. When the mouse cursor is placed over the link, its changes to red and its
font style changes to italic. Notice that the event has in this example are embedded in the
markup. This is one of those cases where the small amount of JavaScript needed does not
justify putting it in a separate file.
<html >
<head>
<title> Dynamic fonts for links </title>
<style type="text/css">
.regText {font: Times; font-size: 16pt;}
</style>
</head>
<body>
<p class="regText">
The state of
<a style="color: blue;"
onmouseover= "this.style.color='red';
Stacking Elements
The top and left properties allow the placement of an element anywhere in
the two dimensions of the display of a document. Although the display is
restricted to two physical dimensions, the effect of a third dimension is possible through the
simple concept of stacked elements, such as that used to stack windows in windowing
systems. Although multiple elements can occupy the same in the document, one is considered
to be on top and is displayed. The top space element hides the parts of the lower elements on
which it is superimposed. The placement of elements in this third dimension is controlled by
the z-index attribute of the element. An element whose z-index is greater than that of an
element in the same space will be displayed over the other element, effectively hiding the
element with the smaller z-index value. The JavaScript style property associated with the z-
index attribute is zIndex.
In the following example, three images are placed on the display so that they overlap. In the
XHTML description of this, each image tag includes an onclick attribute, which is used to
trigger the execution of a JavaScript handler function, First the function defines DOM
addresses for the last top element and the new top element. Then the function sets the zIndex
value of the two elements so that the old top element has a value of 0 and the new top ele-
ment has the value 10, effectively putting it at the top. The script keeps track of which image
is currently on top with the global variable top, which is changed every time a new element is
moved to the top with the toTop function. Note that the zIndex value, as with other
properties, is a string.
<html>
<head>
<title> Dynamic stacking of images </title>
are = "../images/c172.gif"
alt="(Picture of a C172)"
onclick="toTop('C172')" />
<img class="plane2" id= "cix"
src="../images/cix.gif"
alt "(Picture of a Citation airplane)"
onclick="toTop('cix')" />
// stacking.js
// Illustrates dynamic stacking of images
var top= "C172";
// The event handler function to move the given element
// to the top of the display stack
function toTop (newTop) {
// Set the two dom addresses, one for the old top
// element and one for the new top element
domTop document.getElementById(top).style;
domNew = document.getElementById(newTop).style;
// Set the zIndex properties of the two elements, and
reset top to the new top
domTop.zIndex = "0";
domNew. z Index = "10";
top = newTop;
Every event that occurs in an XHTML document creates an event object. This object includes
some information about the event. A mouse-click event is an implementation of the
MouseEvent interface, which defines two pairs of properties that provide geometric
coordinates of the position of the element in the display that created the event. One of these
pairs, client and clienty, gives the coordinates of the element relative to the upper-left corner
of the browser display window, in pixels. The other pair, screenx and screeny, also gives
coordinates of the element but relative to the client computer's screen. Obviously, the former
pair is usually more useful than the latter.
In the following example, where.html, two pairs of text boxes are used to display these four
properties every time the mouse button is clicked. The handler is triggered by the onclick
attribute of the body element. An image is displayed just below the display of the
coordinates, but only to make the screen more interesting.
The call to the handler in this example sends event, which is a reference to the event just
created in the element, as a parameter. This is a bit of magic, because the event object is
implicitly created. In the handler, the formal parameter is used to access the coordinate
properties. Note that the handling of the event object is not implemented the same way in the
popular browsers. The Firefox browsers send it as a parameter to event handlers, whereas
Microsoft
browsers make it available as a global property. The code in where.html works
for both of these approaches by sending it in the call to the handler. It is avail-
able in the call with Microsoft browsers because it is visible there as a global
variable. Of course, for a Microsoft browser, it need not be sent at all.
<?xml version="1.0" encoding="utf-8" ?>
KIDOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
http://www.w3.org/TR/xhtml11/DTD/xhtml1l.dtd">
*)== where.html
Uses where.js
<html>
<head>
<title> Where is the cursor? </title>
<script type="text/javascript" src="anywhere.js">
</script>
</head>
<body onclick="findIt (event)">
<form action = "”>
<p>
Within the client area: <br />
X:
<input type="text" id="xcoorl" size="4" />
Y:
<input type="text" id="ycoorl" size = "4" />
<br /><br />
Relative to the origin of the screen coordinate system:
<br />
X:
<input type="text" id="xcoor2" size = "4" />
y:
<input type="text" id="ycoor2" size = "4" />
</p>
</form>
<p>
<img src="../images/c172.gif" alt="(Picture of C172)" />
</p>
</body>
</html>
//where.js
function findIt (evt) {
document.getElementById("xcoorl").value= evt.clientX;
document.getElementById("ycoorl").value= evt.clientY;
document.getElementById("xcoor2").value= evt.screenX;
document.getElementById("ycoor2").value= evt.screenY;
The following is another example related to reacting to mouse clicks. In this case, the
mousedown and mouseup events are used to show and hide the messsage "Please don't click
here!" on the display under the mouse cursor whenever the mouse button is clicked,
regardless of where the cursor is at the time. The offsets (-130 for left and -25 for top) modify
the actual cursor position an that the message is approximately centered over the cursor
position
<html>
<head>
<title> Sense events anywhere </title>
<script type="text/javascript" src = "anywhere.js">
</script>
</head>
<body onmousedown = "displayIt (event);"
onmouseup = "hideIt();">
<p>
<span id="message" style="color: red; visibility: hidden;
position: relative; font-size: 20pt; font-style: italic;
font-weight: bold;">
Please don't click here!
</span>
<br /><br /><br /><br /><br /><br /><br /><br />
<br /><br /><br /><br /><br /><br /><br /><br />
</p>
</body>
</html>
// anywhere.js
function displayIt (evt) {
var dom = document.getElementById("message");
dom.style.left = (evt.clientX - 130) + "px";
dom.style.top= (evt.clienty - 25)+"px";
dom.style.visibility = "visible";
// The event handler function to hide the message
function hideIt() {
document.getElementById("message").style.visibility =
"hidden";
This causes a 20-millisecond delay, after which the function mover is called. The setInterval
method has two forms. One form takes two parameters, exactly as does setTimeout. It
executes the given code repeatedly, using the second parameter as the interval in milliseconds
between executions. The second form of set Interval takes a variable number of parameters.
The first parameter is the name of a function to be called, the second is the interval in
milliseconds between the calls to the function, and the remaining parameters are used as
actual parameters to the function being called. The example presented here, move Text.html,
moves a string of text from one position (100, 100) to a new position (300, 300). The move is
accomplished by using setTimeout to call a mover function every millisecond until the final
position (300, 300) is reached. The initial position of the text is set in the span element that
specifies the text. The onload attribute of the body element is
used to call a function, initText, to initialize the x and y coordinates for the
initial position to the left and top properties of the element and call the
mover function.
The mover function, named moveText, takes the current coordinates of the text as
parameters, moves them 1 pixel toward the final position, and then calls itself with the new
coordinates using setTimeout. The recomputation of the coordinates is complicated by the
fact that we want the code to work regardless of the direction of the move. One consideration
with this script is that the coordinate properties are stored as strings with units attached. For
example, if the initial position of an element is (100, 100), its left and top property values
both have the string value "100px". To change the properties arithmetically, we must have
them as numbers. Therefore, the property values are converted to numbers in the initText
function by stripping the non digit unit parts. Then, before the left and top properties are set
to the new coordinates, the units (in this case, "px") are catenated back on to the coordinates.
It is interesting that in this example, placing the event handler in a separate file avoids a
problem that would occur if the JavaScript were embedded in the markup. The problem is the
use of XHTML comments to hide JavaScript and having possible parts of XHTML
comments embedded in the JavaScript. For example, if the JavaScript statement x--; is
embedded in an XHTML comment, the validator complains that the in the statement is an
invalid comment declaration. In the JavaScript code of the following example, the
statement x--; is used to move the x-coordinate of the text being moved.In the code file,
moveText.js, note the complexity of the call to the moveText function in the call to
setTimeout. This is required because the call to move Text must be built from static strings
with the values of the variables x and y catenated in.
The JavaScript script for moveText.html is as follows:
--
<html>
<head>
<title> Moving text </title>
<script type="text/javascript" src = "moveTextfuns.js">
</script>
</head>
<!-- Call the initializing function on load, giving the
destination coordinates for the text to be moved
<body onload = "initText()">
<!-- The text to be moved, including its initial position -
<p>
<span id= 'theText' style="position: absolute; left: 100px; top: 100px;
font: bold 20pt Times Roman';
color: blue;"> Jump in the lake!</span>
</p>
</body>
</html>
// This is move Text funs.js - used with moveText.html
var dom, x, y, finalx = 300, finaly = 300;
//
// A function to initialize the x and y coordinates
// of the current position of the text to be moved,
and then call the mover function
function initText() {
dom = document.getElementById('theText').style;
/* Get the current position of the text */
var x = dom.left;
var y = dom.top;
***** //
/* Convert the string values of left and top to
numbers by stripping off the units */
X = x.match(/\d+/);
y = y.match(/\d+/);
/* Call the function that moves it */
moveText (x, y);
} /*** end of function initText */
// A function to move the text from its original
/ position to (finalx, finaly)
function move Text (x, y) {
**** //
/. If the x coordinates are not equal, move
x toward finalx */
if
(x != finalx)
if (x > finalx) x--;
else if (x < finalx) x++;
if (y != finaly)
if (y> finaly) y--;
else if (y < finaly) y++;
/* As long as the text is not at the destination,
call the mover with the current position */
if ((x = finalx) || (y = finaly)) {
}
/* Put the units back on the coordinates before
assigning them to the properties to cause the
move */
dom.left= x + "px";
dom.top= y + "px";
/* Recursive call, after a 1-millisecond delay */
setTimeout("moveText(" + x +","+y+")", 1);
} /*** end of function moveText */
One of the more powerful effects of event handling is allowing the user to drag and drop
elements around the display screen. The mouseup, mousedown, and mousemove events can
be used to implement this. Changing the top and left properties of an element, as we saw
earlier in this chapter, causes the element to move. To illustrate drag and drop, we develop an
example that creates a magnetic poetry system, showing two static lines of a poem and
allowing the user to create the last two lines from a collection of movable words.This
example uses a mixture of the DOM 0 and DOM 2 event models. The DOM 0 model is used
for the call to the handler for the mousedown event. The rest of the process is designed with
the DOM 2 model. The mousedown event handler, ber, takes the Event object as its
parameter. It gets the element to be moved from the currentTarget property of the Event
object and puts it in a global variable so it is available to the other handlers. Then it
determines the coordinates of the current position of the element to be moved and computes
the difference between them and the coordinates of the position of the mouse cursor. These
two differences, which are used by the handler for mousemove and mouseup. . These two
handlers are named mover and dropper, respectively. The dropper handler disconnects
mouse movements from the element-moving process by unregistering the handles mover and
dropper .The following is the document we have just described:
<html>
<head>
<title> Drag and drop </title>
<script type="text/javascript" src = "dragNdrop.js">
</script>
</head>
<body style="font-size: 20;">
<p>
Roses are red <br />
Violets are blue <br />
<span style "position: absolute; top: 200px; left: 0px;
background-color: lightgrey;"
onmousedown = "grabber (event); "> candy </span>
<span style="position: absolute; top: 200px; left: 75px;
background-color: lightgrey;"
onmousedown = "grabber (event); "> cats </span>
<span style "position: absolute; top: 200px; left: 150px;
background-color: lightgrey;"
onmousedown = "grabber (event); "> cows </span>
<span style "position: absolute; top: 200px; left: 225px;
background-color: lightgrey;"
onmousedown = "grabber (event); "> glue </span>
<span style "position: absolute; top: 200px; left: 300px;
background-color: lightgrey;"
onmousedown = "grabber (event); "> is </span>
// dragNDrop.js
var diffx, diffy, the Element;
function grabber (event) {
the Element = event.currentTarget;
var posx = parseInt(the Element.style.left);
var posY = parseInt(the Element.style.top);
diffx = event.clientX - posX;
diffy = event.clienty - posY;
document.addEventListener("mousemove", mover, true);
document.addEventListener("mouseup", dropper, true);
event.stopPropagation();
event.preventDefault();
}
function mover (event) {
theElement.style.left=(event.clientXx - diffX)+"px";
the Element.style.top=(event.clienty - diffY) + "px";
event.stopPropagation();
}
function dropper (event) {
document.removeEventListener("mouseup", dropper, true);
document.removeEventListener("mousemove", mover, true);
event.stopPropagation();