reptile7's JavaScript blog
Saturday, March 29, 2008
 
JavaScript Tom and Jerry, Part 2
Blog Entry #108

As promised, we will in today's post bring the 'cat chases the mouse' script of HTML Goodies' JavaScript Script Tip #91 into the modern era.

Let's start with the mymouse layer. As noted in Blog Entry #94, Netscape's support for the layer element/object began and ended with Netscape 4.x. You can replace the mymouse layer with a div element container if you want, but there's no reason why the animated kitten image itself can't be positioned and then moved around on the page. Accordingly, here's the CSS we'll use:

body { background-color: white; }
#mycat {
position: absolute;
top: 100px;
left: 100px;
border: 0px; }
/* mycat is the id value that we gave to the image in the previous entry. */

However, you probably won't experience any problems if you leave the mymouse layer in place. In the "Notes on invalid documents" section of Appendix B ("Performance, Implementation, and Design Notes") of the HTML 4.01 Specification, the W3C says, If a user agent encounters an element it does not recognize, it should try to render the element's content. A non-Netscape 4.x browser should consequently ignore the mymouse layer and then display normally the animated kitten image - both MSIE 5.1.6 and Netscape 7.02 do just that on my iMac.

You can also keep the script element's Netscape 4.x-specific code and prevent it from throwing errors if you conditionalize it as follows:

Enabling event capture:
if (document.layers) document.captureEvents(Event.MOUSEMOVE);

trackit( ) assignment statements:
if (document.layers) {
document.layers[0].pageX = ev.pageX;
document.layers[0].pageY = ev.pageY; }

As an object-detection if condition, document.layers returns true for Netscape 4.x and (to the best of my knowledge) false for all other browsers, which would therefore skip over the preceding commands.

So now, any Netscape 4.x users out there will still be able to see the script's effect after making the changes described below.

MSIE compatibility

Reference: For a comprehensive description of the MSIE event model, see the MSDN Library's "Understanding the Event Model" article.

In the previous post, we briefly discussed Netscape's event object interface, which has been adopted by the W3C. Internet Explorer utilizes a somewhat-but-not-dramatically different event object interface: in brief, when an event occurs, MSIE's JScript engine 'instantly updates' a pre-existing event object and makes it available to an associated event handler function, in which the keyword event* is used to reference the event object.
(*In the MSIE event model, the event object is actually a 'child object' of the window object, so you can reference the event object with window.event if you prefer.)

Microsoft's event object has clientX and clientY properties that are respectively similar to the pageX and pageY Netscape event object properties but differ therefrom in that they do not take page scrolling into account; for documents whose body content does not exceed the browser window's viewing area, as is the case for the Script Tip #91 Script, clientX/clientY and pageX/pageY are equivalent. The W3C has picked up the clientX/clientY properties (but not the pageX/pageY properties), as has Mozilla (Mozilla retains the pageX/pageY properties).

To make the Script Tip #91 Script work with MSIE, then, we can respectively assign event.clientX and event.clientY to the CSS left and top properties of the mycat image:

// For MSIE 4+:
document.all("mycat").style.left = event.clientX;
document.all("mycat").style.top = event.clientY;
// For MSIE 5+:
document.getElementById("mycat").style.left = event.clientX;
document.getElementById("mycat").style.top = event.clientY;

You may be thinking, "Let's use the name event for the Netscape event object, i.e.,

function trackit(event) {

and then we can use the above document.getElementById("mycat") statements with both MSIE and Netscape." Good idea in theory, but it doesn't work in practice: MSIE threw a 'clientX' is not an object runtime error when I tried this (Netscape executed the statements without incident). To avoid cross-browser errors, either set of MSIE event.clientX/event.clientY statements can be placed in an if (document.all) { ... } conditional, which will be triggered by MSIE 4+ but skipped over by Netscape.

For the MSIE association of the trackit( ) function with the user's mousemoves in the document content area, the script element's document.onmousemove = trackit statement can be used as-is.

Mozilla/W3C compatibility

We now consider current browsers that deploy the Netscape-cum-W3C event object interface. If we continue to use the variable ev for a user mousemove event, then the following trackit( ) code will take care of these browsers:

if (document.getElementById && !document.all) {
document.getElementById("mycat").style.left = ev.clientX;
document.getElementById("mycat").style.top = ev.clientY; }

I've taken the document.getElementById && !document.all condition from the "creating a context menu" example in JavaScript Kit's "Event handling in the DOM" tutorial; this condition should return true for all modern browsers except MSIE and Opera (Opera also supports the all collection).

Before moving on, I wanted to briefly comment on the use of if (window.Event) { ... } conditionals to flag Netscape in WebReference.com's "The Cross-Browser Event Model" column. I am hesitant to recommend this test because I don't know precisely what it tests for. Event (with a capital E) is not a reference for the event object that we've been variabilizing as ev; rather, Event is some sort of behind-the-scenes constructible core object: typeof Event returns function (FYI: typeof Array and typeof Date also return function) and document.write(Event) outputs a function Event() { [native code] } string. You won't find anything about Event, whatever it is, in any of Netscape's or Mozilla's materials; my bet is that, like the captureEvents( ) method, Event is now obsolete.

The addEventListener( ) method

The DOM Level 2 Events Specification introduces an addEventListener( ) method for registering an event handler on an object. The specification negligently does not define the term "event listener" in its "Terminology" section but generally seems to use "event listener" and "event handler" interchangeably (e.g., see this section). The addEventListener( ) syntax can be written as:

object.addEventListener("eventType", functionReference, captTorF)

For applying the addEventListener( ) method to the Script Tip #91 Script:

• The object would be document.

• The "eventType" is "mousemove", the type of event we are 'listening' for.

• The functionReference will be trackit (no parentheses), the function to be triggered by the user's mousemoves.

• As for the captTorF parameter...man, I was hoping to avoid a discussion of event flow/propagation in this post...to make a long story short, captTorF is set to true if we want a DOM ancestor of the "event target" - the source element at which the event occurs, which in this case is the body element - to capture the eventType event and false if we don't. Either true or false works for the Script Tip #91 Script: we want capture to occur at the document object level, but in the absence of capture, a user mousemove will spontaneously 'bubble up' from the body element to the document object (see the "Life Cycle of an Event" section of the aforecited MSDN Library reference; all mouse event types bubble, BTW).

A fly in the ointment: MSIE does not support the addEventListener( ) method but has introduced a similar attachEvent( ) method for registering event handlers:

document.attachEvent("onmousemove", trackit);

However, the Apple Developer Connection's "Supporting Three Event Models at Once" article, which I highly recommend, notes that the attachEvent( ) method works strictly in the IE5+/Windows environment (Mozilla's brief discussion of the attachEvent( ) method omits this crucial fact) and is thus off-limits to a Mac user such as myself (sure enough, the preceding command threw an Object doesn't support this property or method runtime error when I tried it out with MSIE on my computer).

Streamlining/maximizing cross-browser support

(1) The "Accommodating Both Event Object References" section of the aforementioned ADC "Supporting Three Event Models at Once" article provides a 'conditional template' via which we can streamline the above trackit( ) code for all browsers that support the getElementById( ) method as follows:

function trackit(ev) {
ev = ev ? ev : (event ? event : "");
if (ev) {
document.getElementById("mycat").style.left = ev.clientX;
document.getElementById("mycat").style.top = ev.clientY; } }
/* We previously discussed the ?: conditional operator in Blog Entry #101. */

The preceding function accommodates browsers supporting the W3C event model or the MSIE event model; in all cases, the ev variable is used to reference the event object.

(2) In its "Which Binding is Best?" section, the ADC article states, The [property assignment] approach [for event handler registration] is...supported in real life by all but the first-generation scriptable browsers. So we are probably better off sticking with the document.onmousemove = trackit statement, as opposed to using the addEventListener( ) method, for associating the trackit( ) function and the user's mousemoves with the document object.

A right-looking kitty

In Script Tip #91, Joe laments, Do you know how hard it was to find an animated kitty that is looking left? There are thousands of animated cats, but they all look right. Ugh! Joe wanted a left-looking kitty because he wanted the kitty to be looking at the mouse cursor, whose movement sets the position of the upper left-hand corner of the mymouse layer as explained in the previous entry. To transfer the script's effect to a right-looking kitty, the cursor would have to set the position of the upper right-hand corner of the kitty image or its container, and it turns out that this is very easy to do: simply subtract the image/container width from the mousemove clientX/pageX value in the trackit( ) function as shown below.

So, once again, put your mouse cursor in the div below and move it around:

Right-looking animated kitten gif


Meow! I've taken the above image

<img id="mycat" src="images/gersh02.gif" width="125" height="91" alt="Right-looking animated kitten gif" />

from Lisa's Free Original Animated Cat Gifs. The demo uses the following trackit( ) function:

function trackit(ev) {
ev = ev ? ev : (event ? event : "");
if (ev) {

if (!document.getElementById) { // For MSIE 4.x and Netscape 4.x
if (document.all) {
document.all("mycat").style.left = ev.clientX - 125;
document.all("mycat").style.top = ev.clientY; }
if (document.layers) {
document.layers[0].pageX = ev.pageX - 125;
document.layers[0].pageY = ev.pageY; } }

else {
document.getElementById("mycat").style.left = ev.clientX - 125;
document.getElementById("mycat").style.top = ev.clientY; } }

else window.alert("Sorry, your browser does not support the event object."); }

In the next entry, we'll move on to the Script Tips #92-93 Script, which is highlighted by the use of 'two-dimensional' arrays to build a series of tables that pop up in response to mouseover events.

reptile7

Wednesday, March 12, 2008
 
Sic 'im, Kitty
Blog Entry #107

Put your mouse cursor in the div below and move it around:

Animated kitten gif

(This demo should work for you if you're using MSIE or a Netscape/Mozilla/Firefox browser but I can't vouch for other browsers.)

Cool, huh? The above effect is coded by a script offered by HTML Goodies' JavaScript Script Tip #91, our focus for this and the next posts. In truth, the original Script Tip #91 Script makes use of a layer and consequently only works with Netscape 4.x; however, we'll see in due course that the script can be made to work with current browsers without too much difficulty.

The Script Tip #91 Script, which is posted here, is mercifully shorter than some of the scripts that we've been analyzing recently:

<body bgcolor="white">

<script language="javascript">
// (C) copyright 1998 greg bland all rights reserved

function trackit(ev) {
document.layers[0].pageX = ev.pageX;
document.layers[0].pageY = ev.pageY; }

document.captureEvents(Event.MOUSEMOVE);
document.onmousemove = trackit;
</script>

<layer name="mymouse" bgcolor="white" top="100" left="100" z-index="0">
<img src="kittenrunning.gif" />
</layer>

For the sections that follow, we will assume that the user is browsing with Netscape 4.x.

The animated kitten image and the mymouse layer

The animated kitten image that trails the mouse cursor can be accessed at http://www.htmlgoodies.com/legacy/beyond/javascript/stips/kittenrunning.gif and is 51px by 48px; I've doubled its dimensions to make it easier to see:

<img id="mycat" src="images/kittenrunning.gif" width="102" height="96" alt="Animated kitten gif" />

The mycat image is wrapped in a layer element container whose start-tag is:

<layer name="mymouse" bgcolor="white" top="100" left="100" z-index="0">

We previously discussed the name, bgcolor, top, and left attributes of the layer element in Blog Entry #94; the z-index attribute, defined by Netscape here, is unnecessary in this case, as Joe himself admits. (At some point in the future, however, we will deconstruct Netscape's "Swimming Fish" DHTML Example, which gets into the z-index concept.)

Mousemove capture

So, how does the script work? The script's effect is based on the 'capturing' of the user's mousemove events.

Let's impose on the browser window a Cartesian-like coordinate system whose origin, (0,0), is at the upper left-hand corner of the document content area. Our horizontal coordinate, x, increases as we move from left to right; our vertical coordinate, y, increases as we move from top to bottom. The upper left-hand corner of the mymouse layer is initially positioned at (100px,100px). Let's say that we move the mouse cursor from (x1,y1) to (x2,y2). The script's script element reads the values of x2 and y2 and respectively assigns them to mymouse's left and top offsets so that mymouse's upper left-hand corner is now at (x2,y2); if we move the mouse cursor to (x3,y3), then the script moves mymouse's upper left-hand corner to (x3,y3), and so on. In dragging the mymouse layer around in this way, the mouse cursor appears to be 'chased' by mymouse.

What allows us to capture the user's mouse cursor movement and read those xn/yn values is the event object, a client-side object that was once part of JavaScript but was spun off to the DOM with the rest of the client-side objects around 1998 or so. You probably know that Level 2 of the DOM has a separate Events Specification (a Level 3 Events Working Draft is in progress); for its part, Mozilla now provides a DOM event Reference section in its Gecko DOM Reference. Before tucking into these materials, however, I recommend that you read the following, much more user-friendly columns at WebReference.com in their entirety:
(1) The Navigator Event Model
(2) The Internet Explorer Event Model
(3) The Cross-Browser Event Model
To a lesser extent, I also recommend Chapter 10 ("Handling Events") in the JavaScript 1.3 Client-Side Guide, which is confusing in places and is not as helpful as the preceding WebReference.com columns.

The Script Tip #91 Script enables the capture of mousemove events at the level of the document object (i.e., anywhere in the document content area) via the command:

document.captureEvents(Event.MOUSEMOVE);

Comments
• The document object page in the JavaScript 1.3 Client-Side Reference has a short captureEvents( ) method section here, although it's not particularly informative.
• Regarding the captureEvents( ) parameter, I find that the Event part is case-sensitive but the MOUSEMOVE part is not, e.g., mousemove is OK.
• The captureEvents( ) method does not appear in the DOM and is termed "obsolete" by Mozilla. The above command, which is definitely needed by Netscape 4.x to run the script, throws an 'Event' is undefined runtime error when using MSIE; it throws no errors but can be commented out when using Netscape 6+.

We'll use our captured mousemove events to call the script element's trackit( ) function, which moves the mymouse layer around as described earlier and which we'll go through in just a bit. The 'classical' way to tie the execution of the trackit( ) function to a mousemove event in the document content area would be to add an

onMouseMove="trackit( );"

event handler to the body element start-tag. At the time the script was written, however, onMouseMove was not a valid event handler for the document object; indeed, onMouseMove was an event handler for "None [i.e., no objects]" back then. (onMouseMove was unique in this respect; all of the other JavaScript event handlers were associated with at least one object. Currently, [t]he mousemove event...is valid for most elements, according to the W3C.) Fortunately, we can alternatively "register" (associate) onmousemove and the trackit( ) function with the document object via a simple assignment statement:

document.onmousemove = trackit;

This line does not call trackit( ) but assigns its reference to the onmousemove 'property' of the document object. We previously discussed object.onevent = functionName statements in the "Separating the script's HTML and JavaScript" section of Blog Entry #91.

The trackit( ) function

There's no trackit( ) function call in the Script Tip #91 Script; rather, trackit( ) is triggered directly by the user's mousemove events. Here's trackit( ):

function trackit(ev) {
document.layers[0].pageX = ev.pageX;
document.layers[0].pageY = ev.pageY; }

If an event handler function has been registered for an event, then when that event occurs, a corresponding event object is automatically created and passed as a single argument to the handler function. The event object is most often variabilized as e (this is a convention of sorts, much like the use of i as a loop counter variable) but can be given any legitimate variable name, or no name at all: you can use arguments[0] to reference the event object in the handler function if you prefer. As shown above, the Script Tip #91 Script uses the variable ev to represent a user mousemove event.

The event object properties that are relevant to a given event can then be read (and written, in theory at least) via conventional eventObject.property expressions. The following properties apply to a mousemove event: type, target, layerX, layerY, pageX, pageY, screenX, and screenY. The trackit( ) function reads the pageX and pageY properties of each user mousemove event and respectively assigns their values to the pageX and pageY properties of the document's zeroth layer object, i.e., the mymouse layer.
(Although there's no harm in keeping it, the name attribute of the layer element is rendered unnecessary by the use of document.layers[0] expressions here.)

If the mouse cursor is moved from (x1px,y1px) to (x2px,y2px) (cf. the browser window coordinate system described earlier), then ev.pageX will return x2, the cursor's final horizontal position in pixels, and ev.pageY will return y2, the cursor's final vertical position in pixels. That pageX/pageY for a mousemove event return the cursor's final coordinates and not its initial coordinates can be easily verified by monitoring the cursor coordinates with text fields as follows:

(1) Add the form below to the script's document body:

<form action="">
Here's the ev.pageX value: <input name="xcoord" /><br />
Here's the ev.pageY value: <input name="ycoord" />
</form>

(2) Add the following statements to the trackit( ) function:

document.forms[0].xcoord.value = ev.pageX;
document.forms[0].ycoord.value = ev.pageY;

In turn, and as you would infer from the preceding "Mousemove capture" section, the pageX and pageY properties of the layer object are respectively analogous to the left and top attributes of the layer element (they're also respectively analogous to the CSS left and top properties in this case, i.e., when the "containing block" is the "initial containing block").

I suppose I should point out that Joe has his definitions of pageX and pageY reversed: it's pageY that is an offset from the top of the browser screen in regards to the layer itself, whereas pageX is the same, but from the left. Joe's [t]hose top and left [layer offset] values are assigned to ev.pageX and ev.pageY statement is also mixed up; in effect, ev.pageX is assigned to the layer's left offset and ev.pageY is assigned to the layer's top offset, as noted above.

A cross-browser Script Tip #91 Script

We'll save this topic for the next entry, in which we'll also discuss the W3C's addEventListener( ) method and roll out a second demo featuring a 'right-looking' kitty.

reptile7

Sunday, March 09, 2008
 
The World Clock Script: If I Scripted It
Blog Entry #106

Today's post concludes our treatment of the "World Clock" script of HTML Goodies' JavaScript Script Tips #87-90. Below I'll outline some additional changes that I've made to the script in order to create a new-and-improved world clock - you can follow this link to see my clock in the post's "Demo" section.

In the "Let's go to Hong Kong" section of the previous post, we discussed the script's location-specific functions - checkPST( ), checkEST( ), etc. - that provide gmtOffset and zone values to the main checkDateTime( ) function. We've noted that these functions incorrectly adjust the UTC offsets of the script's display locations for daylight-saving time (DST). Moreover but less importantly, it's inefficient to have a separate checkX( ) function for each of the script's location buttons; a group of time zones with the same DST practices (as in the U.S. or in Europe) should be handled by one function if at all possible. Our first order of business, then, is to trade in the original checkX( ) functions for 'better models'.

We sorted out the script's DST problems for the most part in Blog Entry #103's "DST to the millisecond" section, which presented a functional template for correctly carrying out DST adjustments. As for the one-checkX( )-per-button issue, it occurred to me that
(a) the checkX( ) functions can be grouped as needed, and
(b) the checkX( ) gmtOffset and zone values can be set more economically
if we use the script's location buttons to directly feed new Date( ).getTimezoneOffset( ) UTC offsets and zone strings to the generalized checkX( ) functions.

Accordingly, we can for example replace the checkLD( ) function with a EuropeTime( ) function

function EuropeTime( ) {
/* DST runs from 01:00 UTC on the last Sunday in March to 01:00 UTC on the last Sunday in October. */

gmtOffset = arguments[0];
zone = arguments[1];
/* We previously discussed the JavaScript arguments[ ] object in the "Random heterocolor" section of Blog Entry #99. */

dstweek = new Array( );
for (i = 25; i < 32; i++) {
dstweek[i] = new Date("March " + i + ", " + year);
if (dstweek[i].getDay( ) == 0) lastSun = i; }

dstweek2 = new Array( );
for (i = 25; i < 32; i++) {
dstweek2[i] = new Date("October " + i + ", " + year);
if (dstweek2[i].getDay( ) == 0) lastSun2 = i; }

dstbegins = new Date(year, 2, lastSun);
dstends = new Date(year, 9, lastSun2);

if (dstbegins < today && today < dstends) gmtOffset -= 60;
checkDateTime( ); }

that by itself handles gmtOffset and zone values for a row of European London, Berlin, Athens, and Moscow buttons:

<tr>
<td><input type="button" name="reset" value=" London " onclick="EuropeTime(0, this.value);" /></td>
<td><input type="button" name="reset" value=" Berlin " onclick="EuropeTime(-60, this.value);" /></td>
<td><input type="button" name="reset" value=" Athens " onclick="EuropeTime(-120, this.value);" /></td>
<td><input type="button" name="reset" value=" Moscow " onclick="EuropeTime(-180, this.value);" /></td>
</tr>
<!-- During standard time, London, Berlin, Athens, and Moscow observe UTC+0, UTC+1, UTC+2, and UTC+3, respectively. -->

(My EuropeTime( ) function sets its DST goalposts (dstbegins and dstends) not to the millisecond but to the day, because the local user times in Europe's time zones at which standard time is shifted to DST and vice versa are different; for example, in going from standard time to DST, London shifts at 1AM local time, Berlin and Moscow shift at 2AM local time, and Athens shifts at 3AM local time. You could write a separate function for each European time zone, I suppose, but that rather defeats the idea of merging the checkX( ) functions, doesn't it?)

Analogously, my clock replaces
(a) the checkPST( ) and checkEST( ) functions with a USTime( ) function that handles the Pacific, Mountain, Central, and Eastern Time Zones,
(b) the checkFJ( ) function with a NZTime( ) function that takes care of New Zealand and the Chatham Islands, and
(c) the checkTK( ), checkHW( ), checkHK( ), and checkND( ) functions with a NoDST( ) function that can handle any location that does not observe DST:

function NoDST( ) {
gmtOffset = arguments[0];
zone = arguments[1];
checkDateTime( ); }

As for the global UTC offset statements that the checkX( ) functions act on - var PST = 480, var EST = 300, etc. - we don't need them anymore; chuck them out.

Ditching the hour/date/month/year conditionals, or not

In Script Tip #85, Joe notes that a document.write(Date()) command writes to the page a Thu Mar 6 12:41:55 2008-type string. On my computer, the format of this string is browser-dependent: MSIE 5.1.6 outputs Thu Mar 6 12:41:55 2008 whereas Netscape 7.02 outputs Thu Mar 06 2008 12:41:55 GMT-0600. A document.write(new Date()) command produces an almost-identical or identical string: Thu Mar 6 12:49:05 CST 2008 with MSIE and Thu Mar 06 2008 12:41:55 GMT-0600 with Netscape.

In Blog Entry #103, we saw that the original Script Tips #87-90 Script can sometimes generate erroneous last-Saturday dates: '30 February', '31 April', and so on. Upon plugging such dates into document.write( ) commands, I serendipitously discovered that they are automatically 'corrected' by the browsers on my computer, e.g.:

document.write(new Date(2008, 3, 31));
// MSIE outputs Thu May 1 00:00:00 CST 2008

Further experimentation showed that Date objects with similarly invalid month, hour, and minute parameters are also corrected.

The document.write(new Date()) strings bear an obvious resemblance to the dateTime string that the script displays in the face text field. If the browser corrects Date objects as necessary, then we should be able to directly assign a suitable Point B Date object expression to the face value value and thus dispense with the script's various into-a-new-or-prior hour/date/month/year conditionals, and this proves to be the case:

yourOffset = today.getTimezoneOffset( );
ourDifference = gmtOffset - yourOffset;
dateTime = new Date(year, month, date, hour, minute-ourDifference, second);
document.forms[0].face.value = dateTime;

In the above Date object constructor statement, the user minute is adjusted by ourDifference, the user/Point B time difference in minutes; the browser takes it from there.

However, I prefer the original dateTime because it is a cross-browser/platform string, and consequently I am inclined to leave the conditionals in place. And if we were to keep the conditional code, well, it's a bit of a jumble, isn't it? Is there some way we can clean it up, organize it, make it more readable? Here's how I would formulate the checkDateTime( ) conditional section:

if (half != 0) minute -= half;

if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) var leap = true;
else leap = false;

if (minute > 59) { minute -= 60; hour++; }
if (minute < 0) { minute += 60; hour--; }

if (hour > 23) { hour -= 24; date += 1; }

if ((date == 32 && month != 12)
|| (date == 31 && (month == 4 || month == 6 || month == 9 || month == 11))
|| (date == 29 && month == 2 && leap == false)
|| (date == 30 && month == 2))
{ date = 1; month += 1; }
if (date == 32 && month == 12) { month = 1; date = 1; year += 1; }

if (hour < 0) { hour += 24; date -= 1; }

if (date < 1) {
if (month == 1) { month = 12; date = 31; year -= 1; }
else { date = 31; month -= 1; }
if (month == 4 || month == 6 || month == 9 || month == 11) date = 30;
if (month == 2 && leap == false) date = 28;
if (month == 2 && leap == true) date = 29; }

Not a big difference, I admit.

Demo

World Clock






(N.B.: If you're using a browser that will return a standard time getTimezoneOffset( ) value until 6 April (the standard time-to-DST date if the 1987-2006 U.S. DST policy were still in effect), then all of the clock's times will be an hour ahead of the actual times until 6 April (presumably the clock's times will be an hour behind the actual times during 26 October to 2 November). Sorry, there's nothing I can do about this.)

My clock is very much a work in progress, but not a bad start, eh? Most of the world's time zones are covered; conspicuously absent are button rows for South American and African cities.

The clock initially displays the time/date for Reykjavik, Iceland - I wanted a UTC+0 location that does not observe DST.

Australian DST adjustments are handled by two functions: a NSWTime( ) function for cities in New South Wales, South Australia, Victoria, and Tasmania, which observe a common DST policy, and a WATime( ) function for cities in Western Australia, which observes a separate DST policy. (Additional buttons for cities in the Northern Territory and Queensland, which do not observe DST, could be handled by the NoDST( ) function given earlier.)

We'll move on in the next post to the Script Tip #91 Script, which uses the JavaScript event object and event capturing to produce a 'cat chases the mouse' effect.

reptile7


Powered by Blogger

Actually, reptile7's JavaScript blog is powered by Café La Llave. ;-)