Coding The Client
In your travels across the Web, you’ve already seen how client-side scripting can turn even the most static site into an interactive, dynamic experience. Client-side scripting (usually in its most popular avatar, JavaScript) can zoom menus in and out, morph images when a mouse comes near them, and warn you when you enter invalid values into a form.
But JavaScript can do a lot more than this. In addition to manipulating Web pages on an HTTP client, it can also be used to manipulate attributes of the client itself. With JavaScript, you can control the size of the client window, the URL which it’s requesting, the appearance of its toolbars, and many other properties. This control is made available to you, the developer, through a variety of different objects, all of which are good to know if you’re in the business of writing client-side scripts for a Web site or application.
That’s where this tutorial comes in. Over the next few pages, I will be demonstrating some of the JavaScript objects that allow you to exert control over the browser window, its properties and its contents. Some of this may already be familiar to you, especially if you’ve been working with JavaScript for a while. Newbies, on the other hand, should find plenty to entertain themselves with. So come on in, and let’s get going!
Starting At The Top
I’ll begin at the beginning, with the top-level Window object. The Window object is at the top of the DOM hierarchy; all other nodes are under it, including objects representing the document’s frames, forms, images, links and styles. This object comes with a bunch of useful methods, of which the two most commonly-used ones are the open() and close() methods.
Here’s an example of using the Window object’s open() method to open a new browser window:
<script language="JavaScript">
// open a new window
window.open("http://localhost", "new");
</script>
As you will see when you run it in a browser, this line of code opens up a new window and loads the URL “http://localhost” into it. Thus, the first argument to window.open() is always the URL to be loaded, while the second is the window name.
You can also control the appearance of the window, by adding a third argument - a comma-separated list of window attributes. Here’s an example:
<script language="JavaScript">
// open a new window
window.open("http://localhost", "new", "toolbar=no,status=no,menubar=no,scrollbars=no");
</script>
Here’s a brief list of the important attributes that window.open() lets you control:
“width” - controls the width of the new window
“height” - controls the height of the new window
“location” - toggles the address or location box
“toolbar” - toggles the toolbar
“status” - toggles the status bar
“menubar” - toggles the menu bar
“scrollbars” - toggles the scrollbars
“directories” - toggles the directories or links bar
“resizable” - is the window resizable ?
These attributes can be turned on or off by equating them with either a 1 or 0. Height and width values must be specified in pixels.
Thus, if you wanted to open a window with the address bar and status bar off, but the links bar on, you would use this code:
<script language="JavaScript">
// open a new window
window.open("http://localhost", "new", "location=no,status=no,directories=yes");
</script>
while if you wanted a window of height 640 and width 480, non-resizable and with no bars showing, you could use this code:
<script language="JavaScript">
// open a new window
window.open("http://localhost", "new", "width=480,height=640,toolbar=no,resizable=no,menubar=no,location=no,status=no,directories=no");
</script>
Note that leaving the third argument to window.open() empty pops open a window with default settings. Note also that you should not leave spaces between the various window attributes listed in the third argument to window.open() - they can cause problems with certain browsers.
Now, how about closing a window that you’ve opened? It’s pretty easy - just use the window.close() method, as in the following example:
<a href="javascript:window.close()">Close Window</a>
Now, when the user clicks the “Close Window” link above, the window should close automatically. Note that if the window you’re trying to close through JavaScript is the primary browser window, browser security settings might require you to confirm your action through a dialog box.
Moving Windows
You might not know this, but the alert() function you call every time you want a pop-up on your page is actually a method of the Window object. Take a look:
<script language="JavaScript">
// pop up alert
window.alert("I can see you");
</script>
There’s also a window.confirm() method, which displays a confirmation box with a message and two buttons. Depending on the button you pick, the method returns true or false. Take a look at the next example, which demonstrates:
<script language="JavaScript">
// ask a question
var answer = window.confirm("Parlez-vous Francais?");
// process the response
if (answer) { window.alert ("Tres bon, comment allez-vous?"); } else { window.alert ("Illiterate pig!"); }
</script>
Finally, the window.prompt() method pops up an input box and stores the user’s input in a variable. The following example illustrates:
<script language="JavaScript">
// ask for user input
var name = window.prompt("Enter your screen name");
// print it back
window.alert ("Welcome, " + name);
</script>
You can move a window to the front of the window stack by calling the window.focus() method (remember to use the window name when calling this method, or you won’t see anything special happen), and the window.blur() method to move a window to the back of the stack. Consider the following example, which creates a child window and then allows you to move it to the front and back of the window stack using these methods:
<html>
<head>
</head>
<script language="JavaScript">
var newWin = window.open("windows.html", "newWin");
</script>
<body>
<a href="javascript:newWin.blur();">Move child window back</a>
<br>
<a href="javascript:newWin.focus();">Move child window front</a>
</body>
</html>
You can resize a window by calling the window’s resizeTo() method, as in the example below:
<html>
<head>
</head>
<body>
<a href="javascript:var test = window.open('', 'test');"><b>Open test window</b></a>
<p>
<b>Resize test window</b> to:
<ul>
<li><a href="javascript: test.resizeTo(300, 300);">300 x 300</a>
<li><a href="javascript: test.resizeTo(640, 480);">640 x 480</a>
<li><a href="javascript: test.resizeTo(800, 600);">800 x 600</a>
</ul>
<a href="javascript:test.close();"><b>Close test window</b></a>
</body>
</html>
Consider the following example, which allows you to input height and width values into a form, and uses these values to adjust the target window’s height and width appropriately:
<html>
<head>
<script language="JavaScript">
var test = window.open('', 'test');
function changeSize()
{
var width=document.forms[0].winwidth.value;
var height=document.forms[0].winheight.value;
test.resizeTo(parseInt(width), parseInt(height));
}
</script>
</head>
<body>
<form>
Width
<input type="text" size="3" name="winwidth">
Height
<input type="text" size="3" name="winheight">
<input type="button" onClick="javascript:changeSize()" value="Change Window Size">
</form>
</body>
</html>
Bar Tales
The status bar, located at the bottom of the browser window, has long been a territory abused by unimaginative developers. The default text that appears in this area may be altered via the Window object’s “status” property, as in the following example:
<script language="JavaScript">
window.status = "The evil that men do in this bar lives after them"
</script>
A common use of the “status” property is to display a scrolling ticker-tape in the status bar. Here’s how:
<html>
<head>
<script language="JavaScript">
// ticket-tape message
var message = " Yo ho ho and a bottle of rum ";
// set delay
var delay = 75;
function tickerTape()
{
window.status = message;
message = message.substring(1, message.length) + message.substring(0, 1);
window.setTimeout ("tickerTape()", delay);
}
</script>
</head>
<body onLoad="tickerTape()">
</body>
</html>
In this case, I’ve created the appearance of a moving tickertape by taking one character off the beginning of the message string and adding it to the end. Each time the tickerTape() function calls itself, the first character of the string is deleted and added to the end of the string, simulating a scrolling ticker-tape. The setTimeout() function performs this add-and-remove function once every 75 milliseconds. Finally, the “status” property is used to assign the result at each stage to the browser’s status bar.
Navigating The Family Tree
It’s interesting to note, also, that the manner in which you refer to windows changes depending on where you are when you do the referring. In order to close the current window, for example, you can always use
<script language="JavaScript">
// close this window
window.close();
</script>
However, you can also affect other windows, simply by replacing the generic name “window” with the actual name of the window. For example, let’s suppose you want to close a child window (previously assigned the name “baby”) from a parent window.
<script language="JavaScript">
// close the child window named 'baby'
baby.close();
</script>
Thus, JavaScript always understands the generic object name “window” to refer to the current window. To refer to any other window, you should use the corresponding window name.
Let’s look at a simple example to see how this works. Here, the primary window consists of a menu containing links, each of which open up in a child window named “display”. The child window can be closed either from the parent window, by clicking on the “Close Display Window” link, or from the child window itself, by clicking the “Close Me” link. Here’s the code for the menu:
<html>
<head>
</head>
<body>
<ul>
<li><a href="javascript:var display = window.open('http://www.melonfire.com/community/columns/trog/', 'display');">Melonfire</a>
<li><a href="javascript:var display = window.open('http://www.xmlphp.com/', 'display');">XML and PHP</a>
<li><a href="javascript:var display = window.open('http://www.mysql-tcr.com/', 'display');">MySQL: The Complete Reference</a>
</ul>
<a href="javascript:display.close();"><b>Close Display Window</b></a>
</body>
</html>
Notice that I have prefixed the call to close() with the child window name.
Within the pages loaded, there exists a “Close Me” link as well, which can be used to close the child window directly. Here’s what one of the pages loaded into the child window might look like:
<html>
<head>
</head>
<body>
<!-- page content for link here -->
<!-- close window link -->
<a href="javascript:window.close();">Close Me!</a>
</body>
</html>
In this case, since I’m closing the current window, I can use window.close() directly without worrying about the window name.
Thus far, I’ve shown you how to control the child window from the parent. It’s also possible to work the other way around, controlling the parent window from the child. Every Window object exposes an “opener” property, which contains a reference to the window that created it. Therefore, even if you don’t know the name of the parent window, it’s still possible to access and manipulate it via this “opener” property.
Let’s take a look at a simple example, resizing the parent window from the child:
<html>
<head>
</head>
<body>
<!-- page content for link here -->
<!-- resize parent window -->
<a href="javascript:opener.resizeTo(400,400);">Resize My Parent</a>
</body>
</html>
Location Is Everything
If it’s the browser URL you want to manipulate, you can’t go wrong with the Location object, which exists under the Window object. This object has two important methods and three important properties - the latter are illustrated in the example below:
<script language="JavaScript">
window.alert("URL = " + location.href + "\nHost = " + location.host + "\nProtocol = " + location.protocol)
</script>
The “href”, “host” and “protocol” properties of the Location object return the current URL, host name and protocol being used respectively. Of these, you can use the “href” property to redirect the browser to a new URL, simply by giving it a new value. The following example shows you how:
<script language="JavaScript">
// send browser to new URL
window.location.href = "http://www.melonfire.com/";
</script>
An alternative way to accomplish the above is to redirect the browser to a new URL with the replace() method, as in the following example:
<script language="JavaScript">
// send browser to new URL
window.location.replace("http://localhost/aa");
</script>
You can also refresh the page by reloading it with the browser’s current URL with the reload() method. This method comes in particularly handy if you need to refresh a page at a pre-defined interval. Consider the following example, which illustrates:
<script language="JavaScript">
setTimeout("location.reload()",600000)
</script>
Here, I’ve set a timeout for the page that makes it reload every 600000 milliseconds, or 10 minutes, by combining the setTimeout() method with the location.reload() method.
History Lesson
As you travel from one Web site to another, most browsers record the URLs you visit in a history buffer, allowing you to return to them at any time with a single click. This history buffer is accessible to you via the History object, which exposes methods and properties for moving forward and backward through the list of recently-accessed URLs.
In order to access the last URL in the, you would use the history.back() method (equivalent to hitting the browser’s “Back” button),
<script language="JavaScript">
// go back
window.history.back();
</script>
while the history.forward() method lets you access the next URL in the history list (equivalent to hitting the browser’s “Forward” button).
<script language="JavaScript">
// go forward
window.history.forward();
</script>
Here’s an example which illustrates how these two methods can be used to build a simple navigation toolbar:
<form>
<input type="button" name="back" value="Back" onClick="javascript:history.back();">
<input type="button" name="next" value="Forward" onClick="javascript:history.forward();">
</form>
You can obtain the total number of items in the history list through the History object’s “length” property, as below:
<script language="JavaScript">
// display number of items in history list
alert(history.length);
</script>
You cannot access the elements of the history list directly - however, you can tell the browser to go to a particular URL from the history list with the history.go() method, which accepts an offset indicating which URL in the history list to go to. In this system, the current URL is always 0 - which means that you can go one step back with
<script language="JavaScript">
// go back
window.history.go(-1);
</script>
which is equivalent to
<script language="JavaScript">
// go back
window.history.back();
</script>
Finally, note that the History object is limited to storing URLs that have been visited in that window itself. To access history items in other windows, use the window name as prefix.
Down To The Document
Under the top-level Window object, comes the Document object. This object represents the head and body of the HTML page loaded in the browser, including all its images, forms and links. Like the Window object, this one too comes with its own methods and properties.
One of the Document object’s commonly-used properties is the write() method, which can be used to write text to the Web page at run-time. Take a look at the following example, which demonstrates how this works:
<html>
<head>
<script language="JavaScript">
function writeToDoc()
{
// retrieve value of user input
var text = document.forms[0].elements[0].value;
// open document and write to it
document.open();
document.write("<html><head><body>This is what you said: <br /><i>" + text + "</i></body></head></html>");
// close and display
document.close();
}
</script>
</head>
<body>
<form>
Say something <input type="text" size="20">
<input type="button" onClick="writeToDoc()" value="Write!">
</form>
</body>
</html>
Here, when the user enters some data into the form input box and clicks the “Write!” button, the writeToDoc() function is invoked. This function first reads the data entered by the user into a variable, then begins writing to the document. This writing process consists of first opening a stream to the document with document.open(), then writing to it with document.write() and then closing the stream with document.close(). The data written to the document is displayed only after document.close() is called.
As the example above illustrates, these methods make it possible to dynamically alter the contents of a page with JavaScript. Using DOM access methods, you can even focus the document.write() method on specific elements of the pages, writing - for example - directly inside a <div>
or altering form contents on the fly, in response to user input or external events.
All the other elements of the page - forms, links, images - are organized under the Document object as arrays. Using the Document object as base, therefore, it’s easy to access any of these elements and manipulate them (I’ve done this in some of the previous examples, to access form values). Take a look at this next example, which uses these object arrays to return some statistics about the number of links, images and forms within the document:
<html>
<head>
</head>
<body>
<!-- add some elements to the page -->
<form>
<input type="text" size="20">
<input type="button" value="Click me">
</form>
<a name="link1" href="link1.htm">
<image name="image1" src="image1.jpg" width=20 height=20>
</a>
<a name="link2" href="link2.htm">
<image name="image2" src="image2.jpg" width=20 height=20>
</a>
<a name="link3" href="link3.htm">
<image name="image3" src="image3.jpg" width=20 height=20>
</a>
<image name="image4" src="image4.jpg" width=20 height=20>
<form>
<input type="text" size="20">
<input type="button" value="Click me">
</form>
<script language="JavaScript">
// count the elements of each type and print
document.write("<br/>Links = " + document.links.length + "<br/> Images = " + document.images.length + "<br /> Forms = " + document.forms.length)
</script>
</body>
</html>
Since the images, forms and links within a document are structured as arrays under the Document object, it’s easy to calculate the total number of items of each type - simply obtain the size of the corresponding array.
Of course, there’s a lot more you can do with the Document object. Sadly, however, most of it involves manipulating the contents of the HTML document, not of the browser displaying it, and therefore doesn’t fall under the ambit of this tutorial. If you’re interested, though, you will find the following links most instructive:
http://msdn.microsoft.com/workshop/author/dhtml/reference/objects/obj_document.asp
http://www.mozilla.org/docs/dom/domref/
http://devedge.netscape.com/library/manuals/2000/javascript/1.5/reference
http://devedge.netscape.com/library/manuals/2000/javascript/1.3/guide/navobj.html
http://www.wdvl.com/Authoring/JavaScript/Tutorial/
http://hotwired.lycos.com/webmonkey/javascript/tutorials/tutorial1.html
http://www.pageresource.com/jscript/
And that’s about all I have time for at the moment. See you soon!
Note: Examples are illustrative only, and are not meant for a production environment. Examples have been tested on Microsoft Internet Explorer 5.x only. Melonfire provides no warranties or support for the source code described in this article. YMMV!
This article was first published on 21 Nov 2003.