The document object is associated with the Web page appearing in the browser. It is a property of the window object and is also an object itself which includes properties and methods that permit JavaScript control over the look and feel of the current XHTML document.
Document properties are script accessible for reading and writing with a reference in the general format shown in Figure 8-1.
document.property |
Common properties of the document object are described in the following table. Some of the document properties can be set with scripting; others are read-only.
| Property | Description |
|---|---|
| bgColor | The color of the document background (read/write). |
| fgColor | The color of the document foreground text (read/write). |
| title | The title appearing in the <title> tag of the current document (read-only). |
| referrer | The URL of the document from which the user linked to the current document by clicking
an <a> link (read-only). |
| lastModified | The date on which the current document was last changed (read-only). |
| linkColor | The color of text for a link that the user has not yet visited (read/write). |
| vlinkColor | The color of text for a link that the user has already visited (read/write). |
| alinkColor | The color of text for a link that the user clicks (read/write). |
Scripting Document Colors
Some of these document properties have style sheet equivalents. For instance, the bgColor and fgColor properties are equivalent to the background-color and color style properties, respectively. Still, it is always preferable to use CSS style properties when scripting style changes for compatibility with standards.
Document colors can be set dynamically, although it is questionable whether this is a good idea. Supposedly, your colors were chosen because they best presented your page contents. If, though, you wish to provide color alternatives, you can make these colors user selectable. In the following example, a range of background and foreground colors can be chosen by clicking radio buttons.
<script type="text/javascript"> function ChangeBackground(Color) { document.bgColor = Color; // style sheet equivalent: document.body.style.backgroundColor = Color } function ChangeForeground(Color) { document.fgColor = Color; // style sheet equivalent: document.body.style.color = Color } </script> <b>Background Color:</b><br/> <input type="radio" name="BG" onclick="ChangeBackground('red')"/>Red <input type="radio" name="BG" onclick="ChangeBackground('green')"/>Green <input type="radio" name="BG" onclick="ChangeBackground('blue')"/>Blue <input type="radio" name="BG" onclick="ChangeBackground('black')"/>Black <input type="radio" name="BG" onclick="ChangeBackground('white')"/>White <br/><br/> <b>Foreground Color:</b><br/> <input type="radio" name="FG" onclick="ChangeForeground('red')"/>Red <input type="radio" name="FG" onclick="ChangeForeground('green')"/>Green <input type="radio" name="FG" onclick="ChangeForeground('blue')"/>Blue <input type="radio" name="FG" onclick="ChangeForeground('black')"/>Black <input type="radio" name="FG" onclick="ChangeForeground('white')"/>White
A color choice is passed to the functions where the string is received as argument Color. This argument is assigned to the document.bgColor or document.fgColor property. The commented lines of code show the equivalent style sheet settings.
Link colors (linkColor, avlinkColor, and alinkColor) can also be set dynamically. Again, preference should be to assigning these colors permanently with style sheets and not permitting changes.
Scripting Document Links
A document's title property can be useful when scripting links between pages. Consider the following scenario. In a frameset you have two frames. A Links frame contains links to each of the pages of a Web site; other links identified as "Prev" and "Next" link to the previous or next page in sequence. A Contents frame displays the page to which a link is made.
What is interesting about his application is that none of the links is hard-coded. All links are created and all navigations between pages are handled by scripts on the Links.htm page appearing in the Links frame. In this way you can maintain all navigation links in a central script and never have to code links on individual pages.
The following listing shows the Site.htm page that creates the frameset and loads the initial set of pages into the frames.
<html> <head> <title>Site</title> </head> <frameset cols="25%,*"> <frame name="Links" src="Links.htm"/> <frame name="Content" src="Page1.htm"/> </frameset> </body> </html>
All the effort in setting up links is isolated in scripts on the Links.htm page. Full coding for this page is shown below. Notice that the body of the document contains a division (id="Links") to which the script writes all links appearing on the page.
<html> <head> <title>Link Page</title> </head> <script type="text/javascript"> var Title = new Array(); var Curr = new Array(); var Prev = new Array(); var Next = new Array(); function BuildLinks() { Title[0]="Page 1"; Curr[0]="Page1.htm"; Prev[0]="Page3.htm"; Next[0]="Page2.htm" Title[1]="Page 2"; Curr[1]="Page2.htm"; Prev[1]="Page1.htm"; Next[1]="Page3.htm" Title[2]="Page 3"; Curr[2]="Page3.htm"; Prev[2]="Page2.htm"; Next[2]="Page1.htm" for (i=0; i < Title.length; i++) { document.getElementById("Links").innerHTML += "<a href='" + Curr[i] + "' target='Content'>" + Title[i] + "</a><br/>"; } document.getElementById("Links").innerHTML += "<br/>"; document.getElementById("Links").innerHTML += "<a href='javascript:' onclick='GoLink(\"prev\")'>Prev</a> "; document.getElementById("Links").innerHTML += "<a href='javascript:' onclick='GoLink(\"next\")'>Next</a>"; } function GoLink(Direction) { var CurrentTitle = parent.Content.document.title; for (i=0; i < Title.length; i++) { if (Title[i] == CurrentTitle) { if (Direction == "prev") { parent.Content.location = Prev[i]; } else if (Direction == "next" ) { parent.Content.location = Next[i]; } break; } } } </script> </head> <body onload="BuildLinks()"> <h3>Links</h3> <div id="Links"></div> </body> </html>
When this page is loaded, the BuildLinks() function is called by the onload event handler of the <body> tag to create the links on this page. The script maintains all linking relationships in a set of four corresponding arrays declared as global for access by all functions on the page. Declarations of these arrays and their loading at the beginning of the BuildLinks() function are repeated below.
<script type="text/javascript">
var Title = new Array();
var Curr = new Array();
var Prev = new Array();
var Next = new Array();
function BuildLinks()
{
Title[0]="Page 1"; Curr[0]="Page1.htm"; Prev[0]="Page3.htm"; Next[0]="Page2.htm"
Title[1]="Page 2"; Curr[1]="Page2.htm"; Prev[1]="Page1.htm"; Next[1]="Page3.htm"
Title[2]="Page 3"; Curr[2]="Page3.htm"; Prev[2]="Page2.htm"; Next[2]="Page1.htm"
...
}
Array Title holds the page titles coded in the <title> tag of each page of the site. It holds the identities of the various pages. Array Curr gives the URL associated with each page title, and arrays Prev and Next hold the URLs to which previous and next links are made. In short, these four arrays contain all the information needed to identify and link to pages, and to link from one page to the next. For instance, if the page with the title "Page 1" is currently being displayed in the Contents frame, then it can be determined from the arrays that the URL of this page is "Page1.htm", that a link to the previous page is to "Page3.htm", and a link to the next page is to "Page2.htm".
After building the arrays, function BuildLink() proceeds to create the links appearing on the Links.htm page. This portion of the function is repeated below.
function BuildLinks()
{
...
for (i=0; i < Title.length; i++) {
document.getElementById("Links").innerHTML +=
"<a href='" + Curr[i] + "' target='Content'>" + Title[i] + "</a><br/>";
}
...
}
Creating links involves formatting <a> tags for each of the site pages. The Title array is iterated and a link is made by concatenating the strings
"<a href='" +to produce the following three links and assigning them to the output division's innerHTML property:
<a href='Page1.htm' target='Content'>Page 1</a><br/> <a href='Page2.htm' target='Content'>Page 2</a><br/> <a href='Page3.htm' target='Content'>Page 3</a><br/>
Finally, <a> tags are created for the "Prev" and "Next" links and concatenated within the output division.
function BuildLinks()
{
...
document.getElementById("Links").innerHTML += "<br/>";
document.getElementById("Links").innerHTML +=
"<a href='javascript:' onclick='GoLink(\"prev\")'>Prev</a> ";
document.getElementById("Links").innerHTML +=
"<a href='javascript:' onclick='GoLink(\"next\")'>Next</a>";
}
This code produces the following two links:
<a href='javascript:' onclick='GoLink("prev")'>Prev</a>
<a href='javascript:' onclick='GoLink("next")'>Next</a>
These links call function GoLink(), passing to it the string "prev" or "next" depending on which link is clicked. Therefore, the function is informed of which direction to navigate from the current page.
Function GoLink() handles navigation from the current page to the previous or next page. It receives the direction of navigation passed to it ("prev" or "next") through argument Direction.
function GoLink(Direction)
{
var CurrentTitle = parent.Content.document.title;
for (i=0; i < Title.length; i++) {
if (Title[i] == CurrentTitle) {
if (Direction == "prev") {
parent.Content.location = Prev[i]; }
else if (Direction == "next" ) {
parent.Content.location = Next[i]; }
break;
}
}
}
The function first needs to determine the page currently being displayed in the Content frame. This information is given by the title property of the document currently occupying the frame: parent.Content.document.title. In this reference, parent specifies the frameset containing the current frame (Links) from which this reference is made; .Content specifies the name of the frame containing the .document of interest; and .title specifies the entry in that page's <title> tag. That document's title is assigned to variable CurrentTitle.
Now, the Title array is iterated to find a matching title. When a match is made, corresponding elements of the Prev and Next arrays hold the URLs of the pages to which to navigate. One of the two URLs is assigned to the parent.Content.location property of the Content frame depending on the Direction argument passed to the function. Recall that the location property is a reference to the URL of a document occupying a window (or frame in this case). By assigning a URL to this property, the page is loaded into the window.
Since all navigation for the site is localized in the script of the Links.htm page, it becomes relatively easy to add and delete site pages and to maintain changing links. When new pages are added to the site, for example, their titles, URLs, and previous and next links are simply added to the arrays. There is no requirement to modify XHTML coding or to recode the functions. Only the "data" changes.
Using Document Referrer
The document.referrer property indicates the page from which a link was made. You can, therefore, discover the page or site from which visitors arrive at your site, or determine the path through which visitors navigate your site. Assume, for example, that you have a "private" page that should not viewed without going through a "logon" page to validate the visitor's access privileges. To ensure that visitors always arrive at your "private" page via your "logon" page, your "private" page can check its document.referrer property.
In the following script, the CheckReferrer() function is called when this Private.htm page is loaded. The function looks for the string "Login.htm" as part of the URL of the page from which this page was linked. If "Login.htm" is not part of the document.referrer URL, then arrival at this page was not through the Login.htm page, and that page is immediately loaded.
<script type="text/javascript"> function CheckReferrer() { if (document.referrer.indexOf("Login.htm") == -1) { window.location = "Login.htm"; } } </script> <body onload="CheckReferrer()"> ...
Page Modification Date
Property document.lastModified retrieves the date on which a Web page was last modified. This information is often provided for a page so the visitor can determine when it was last updated, saving the visitor from having to scan the page looking for new information. The following output and inline script gives the date on which this current page was last updated.
Last modified on:
<script type="text/javascript">
document.write(document.lastModified);
</script>
Document Body Properties
There are certain properties of the document occupying the browser window that are accessible through the document's body object. These references are are in the following format.
document.body.property |
Common properties of the document.body object are described in the following table. Some of the properties can be set with scripting; others are read-only. Notice that certain of these properties have style sheet equivalents. In these cases, you should use the CSS properties when getting or setting these styles.
| Property | Description |
|---|---|
| background | The URL of the background image for the document, if any (read/write). CSS equivalent:
background-image(url). |
| bgProperties | Indicates whether the background image for the document is fixed
or scrolls with the page content (read/write). A scrolling background image is the default and is set
by an empty string. CSS equivalent: background-attachment(fixed|scroll). |
| topMargin | The number of pixels of white space at the top of the document (read-only). CSS equivalent:
margin-top:npx (read/write). |
| rightMargin | The number of pixels of white space on the right of the document (read-only). CSS equivalent:
margin-right:npx (read/write). |
| bottomMargin | The number of pixels of white space at the bottom of the document (read-only). CSS equivalent:
margin-bottom:npx (read/write). |
| leftMargin | The number of pixels of white space on the left of the document (read-only). CSS equivalent:
margin-left:npx (read/write). |
| innerText | The text (but not the XHTML) on the page (read/write). CSS equivalent: same. |
| innerHTML | The text, including the XHTML, on the page (read/write). CSS equivalent: same. |
| clientWidth | The width in pixels of the viewable area of the document (read-only). |
| clientHeight | The height in pixels of the viewable area of the document (read-only). |
| scrollWidth | The width in pixels of the scrollable area of the document. Same as
clientWidth if no horizontal scroll bar is present (read-only). |
| scrollHeight | The height in pixels of the scrollable area of the document. The full height of the
document within the window (read-only). |
| scrollLeft | The number of pixels by which the document is scrolled horizontally to the left
(read/write). |
| scrollTop | The number of pixels by which the document is scrolled vertically from the top of
the document (read/write). |
The document.body object responds to user events just like other page elements. It recognizes mouse events, load events, and others. Also, it responds to scroll events that occur when the user moves the scroll bar or mouse scroll wheel to scroll the page. These scroll events are trapped with an onscroll event handler coded in the <body> tag. In fact, any scrollable page element has an onscroll event handler that can trigger scripts.
As an example of trapping and responding to scroll events, click the following button to display a "floating" menu containing links to sections of this page. The menu maintains its fixed position in the document window during page scrolling.
The menu is a division configured as shown below. The division must contain a position:absolute style setting in order to adjust its page position with scripting. It is positioned a fixed number of pixels from the left margin of the page; its vertical position is not fixed, being calculated by a script that always positions it 30 pixels beyond the current scroll position of the page.
<div id="Menu" style="position:absolute; width:200px; height:160px;
left:365px; border:ridge 3px; padding:10px; background-color:#F0F0F0">
<h4 style="text-align:center">Menu</h4>
<a href="#HEAD1">Scripting Document Colors</span></a><br/>
<a href="#HEAD2">Scripting Document Links</span></a><br/>
<a href="#HEAD3">Using Document Referrer</span></a><br/>
<a href="#HEAD4">Page Modification Date</span></a><br/>
<a href="#HEAD5">Document Body Properties</span></a><br/>
<a href="#HEAD6">Scrolling Events</span></a><br/>
<br/>
<input type="button" value="Hide"
onclick="document.getElementById('Menu').style.visibility='hidden'"/>
</div>
As you can tell by their href attributes, links are to on-page sections identified by <a name="name"> links. These links are associated with side headings appearing on the page.
Positioning of the division during scrolling is handled by the ScrollMenu() function. It is called by an onscroll event handler coded in the <body> tag to respond to any scroll event associated with the page.
<script type="text/javascript"> function ScrollMenu() { document.all.Menu.style.top = document.body.scrollTop + 30; } </script> <body onscroll="ScrollMenu()">
The position of the menu division is based on the current scroll position of the page. The number of pixels the page is currently scrolled from the top of the document is given by the document.body.scrollTop property. The function sets the menu division's top style property to 30 pixels beyond the current scrollTop position of the page. Each time the page is scrolled, this calculation is made to keep the menu division in the same position in the browser window.
The following button displays a small scroll box using the same scrolling and positioning properties as the previous menu division. Click and hold down the mouse over the up or down arrows to scroll this page. The scroll box moves with the document scroll to maintain its fixed position in the browser window.

This scroll box is also designed within a <div> tag as shown below. The division contains arrow images along with a separator division that can be clicked to hide the scroll box.
<div id="Scroller" style="position:absolute; visibility:hidden; width:20px; height:100px; left:200px; border:solid 1; background-color:#F0F0F0"> <img src="Up.gif" onmousedown="ScrollUp()" onmouseup="ScrollStop()" onmouseout="ScrollStop()"/><br/> <div style="width:20px; height:20px; background-color:#000000" border:solid 0" title="Click to Hide" onclick="document.getElementById('Scroller').style.visibility='hidden'"> </div> <img src="Dn.gif" onmousedown="ScrollDn()" onmouseup="ScrollStop()" onmouseout="ScrollStop()"/> </div>
Scrolling continues as long as the mouse button is held down on the images. Therefore, it is necessary to establish an interval timer to continue scrolling until the button is released. For example, on a mousedown event for the up arrow, the onmousedown event handler calls the ScrollUp() function. This function, shown below, sets an interval timer (ScrollTimer) to call the GoUp() function every 50 milliseconds. The GoUp() function sets the scrollTop property of the document to its current setting minus 20 pixels. So, the page scrolls up by 20 pixels every 50 milliseconds as long as the mouse button is down on the image.
<script type="text/javascript">
function ScrollUp() {
ScrollTimer = setInterval("GoUp()", 50);
}
function ScrollDn() {
ScrollTimer = setInterval("GoDn()", 50);
}
function GoUp() {
document.body.scrollTop -= 20;
}
function GoDn() {
document.body.scrollTop += 20;
}
function ScrollStop() {
clearInterval(ScrollTimer);
}
</script>
At the same time the page scrolls, the position of the scroll box is adjusted to follow along, using a similar technique as for the previous menu division. Scrolling is controlled from the <body> tag, calling the ScrollScroller() function for every scroll event associated with the page.
<script type="text/javascript"> function ScrollScroller() { document.getElementById("Scroller").style.top = document.body.scrollTop + (document.body.clientHeight / 2) - 50; } </SCRIPT> <body onscroll="ScrollScroller()"> ...
In this case, the scroll box is always positioned vertically in the middle of the window containing the document. To make the calculation, you need to know the current scroll position of the document and the dimensions of its viewable area. The current scroll position of the document is given, of course, by document.body.scrollTop; the vertical center of the viewable area is determined from its size. These dimensions are given by the clientWidth and clientHeight properties, the pixel sizes of the window in which the document appears. The vertical center of the viewable area, therefore, is clientHeight / 2 pixels. When this amount is added to the current scrollTop setting for the page, it gives the total number of pixels from the top of the document that equate with the center of the display window.
This vertical pixel position would be the location of the top-left corner of the scroll box if it were positioned there. However, the box needs to be offset by half its height towards the top of the document in order for the box itself to appear in the middle. Therefore, this offset (50 pixels, half the height of the scroll box) is subtracted from the vertical center of the display area.
On a mouseup event associated with the up or down arrow, the ScrollStop() function is called. This function clears the timer, stopping the call to GoUp(), thereby stopping the scroll.
If, however, the mouse is moved off the up or down arrow during scrolling, a mouseup event does not register and the timer does not get cleared. Scrolling continues. This situation is resolved by trapping for a mouseout event for these images. An onmouseout="ScrollStop()" event handler appears in the image tags to stop scrolling in case the mouse is moved off the images.