reptile7's JavaScript blog
Wednesday, December 27, 2017
 
A JavaScript 1.2 Calendar and Clock, Part 4
Blog Entry #386

Image clock miscellany

I've got a bit more to say about the Multiple Java Calendar script's image clock before we move on to its calendar.

Image availability

For whatever reason, JavaScript Goodies is missing the following image clock images:
(1) the dgcol.gif colon image;
(2-4) the dgm.gif, dga.gif, and dgp.gif a.m./p.m. images (all three of them); and
(5-6) the dg-1.gif and dg-2.gif digit images.
The other digit images and the dgbl.gif and calcbl.gif blanks can be accessed and downloaded via their https://www.htmlgoodies.com/JSBook/image_file_name URLs, e.g., https://www.htmlgoodies.com/JSBook/dg7.gif will take you to the 7 image.

In contrast, all of the image clock images are available at Pagetools.de's "Index of /java/scripts4/kalend3" directory - get them there.

Image dimensions

Excepting the dgcol.gif image, all of the image clock images are dimensions-wise 16px by 21px. As detailed here in Blog Entry #384, the non-colon images are all loaded into 12px by 15px <img>s. Do we really want to be shrinking these guys? I'd say no, they're small enough as it is, although you may feel differently.

For its part, the dgcol.gif image is 11px by 21px and is loaded into an <img> whose height is again 15px but whose width is unspecified; in this case I would halve the original width to 6px and leave the original height alone.

Image preloading

The Script Tips #84-86 script preloads the digit and a.m./p.m. images but the js-caltop1.html scripts[0] script doesn't. Given modern processor speeds, and that all of the images for both scripts have a 4 KB file size, you wouldn't think preloading would be necessary, but that said, it certainly isn't a bad idea by any stretch to preload the aforementioned images, and doing so only takes a few lines of code:

/* Place these statements at the beginning of the scripts[0] script, just before the date( ) function declaration: */
var digitImgs = new Array(10);
for (var i = 0; i < digitImgs.length; i++) { digitImgs[i] = new Image( ); digitImgs[i].src = "dg" + i + ".gif"; }
var amImg = new Image( ), pmImg = new Image( );
amImg.src = "dga.gif"; pmImg.src = "dgp.gif";
/* There's no point in preloading the dg-1.gif and dg-2.gif images if we don't need to use them in the first place. */


HTML vs. JavaScript images

If the image width and height information is moved to a style sheet or isn't specified at all, then the clock <img>s can be written as normal HTML, which would be my preference. On the other hand, there's something to be said for coding the clock as an externalizable JavaScript widget, in which case I would lose the document.write( ) action in favor of its modern-day DOM equivalent:

<div id="clockDiv"></div>
...
var imgNames = ["hour1", "hour2", "colon", "min1", "min2", "sec1", "sec2", "noon1", "M"];
for (var i = 0; i < imgNames.length; i++) {
    var clockImg = document.createElement("img");
    clockImg.name = imgNames[i];
    if (i == 2) clockImg.src = "dgcol.gif";
    else if (i == 8) clockImg.src = "dgm.gif";
    else clockImg.src = "calcbl.gif";
    document.getElementById("clockDiv").appendChild(clockImg);
    if (i == 4 || i == 6) document.getElementById("clockDiv").appendChild(document.createTextNode(" ")); }


With today's browsers, var clockImg = new Image( ); can be used in place of var clockImg = document.createElement("img");.

The head form

As detailed in the previous post, a head form containing four hidden controls

<form name="head">
<input name="hour" type="hidden">
<input name="min" type="hidden">
<input name="sec" type="hidden">
<input name="noon" type="hidden">
</form>


precedes the scripts[0] script. Near the end of the date( ) function - between the sec if...else if...else if... cascade and the window.setTimeout("date( );", 1000); recursive date( ) call - is a set of three statements

document.head.hour.value = hour;
document.head.min.value = min;
document.head.sec.value = sec;


that assigns hour, min, and sec to the values of the first three head inputs. No subsequent use is made of the head data set and consequently all of this code can be thrown out.

We will later use the hidden inputs of the line form to pass day, month, and year information to the js-calbot2.html calendar code and I suspect the author similarly wanted to make the hour/min/sec data available to the js-calbot2.html source via the head form even though js-calbot2.html does not in practice act on that data.

In the name of completeness

• Because we want a new image in the <img name="sec2"> placeholder every second and because a date( ) run does take a finite amount of time, I would argue that the 1000 setTimeout( ) delay should be slightly decreased, say, to 900. Moreover, Mozilla would recommend that we convert window.setTimeout("date( );", 900); to window.setTimeout(date, 900);.

• Finally, I don't like the date( ) function name - we're getting the time, not the date - we should change it to createClock( ) or something like that. Even if I were inclined to keep the date( ) name, W3Schools.com advises, You should [also] avoid using the name of JavaScript built-in objects, properties, and methods [as variables, labels, or function names], and date( ) is identifier-wise too similar to Date( ) for my taste.

Pre-calendar

Clicking the button

<input name="butt" type="button" value=" Show Calendar " onclick="compute(this.form); window.open('js-calbot2.html', target='frame2');">

in the right cell of the js-caltop1.html layout table calls a compute( ) function and loads the js-calbot2.html document into the frame2 frame of the javacalendar.html frameset. The compute( ) function is the last function in the js-caltop1.html source and is the only function in the scripts[2] script; it works with the hidden inputs of the line form

/* Upon closing the layout table's center cell: */
yr = document.isnform.showyear.value;
t = new Date( );
document.write("<form name='line'>");
document.write("<input name='res' type='hidden'>");
document.write("<input name='day' type='hidden' value='1'>");
document.write("<input name='month' type='hidden' value='" + (t.getMonth( ) + 1) + "'>");
document.write("<input name='year' type='hidden' value='19" + t.getYear( ) + "'>");
document.write("<input name='result' type='hidden' value=''>");
document.line.year.value = yr;
function compute(form) { ... }


to determine the day of the week that the first day of the calendar month will fall on, e.g., "Friday" for December 2017.

As shown above, a run of top-level code prior to the compute( ) declaration
(i) assigns the showyear text field's value, 19117 for the year 2017, to a yr variable,
(ii) constructs a new t Date object, which supersedes the t Date object constructed in the scripts[1] script,
(iii) writes out the line form's start tag and hidden inputs, and
(iv) assigns yr to the value of the year hidden field.

The compute( ) body begins simply enough by switching the butt button label to Update Calendar.

document.line.butt.value = "Update Calendar";

Let's wait until the next post to discuss the rest of compute( ), which is kind of...strange: strange because of its inexplicable arithmetic and strange because we could be getting the desired day of the week string with just a few lines of code vs. the 30+ lines that compute( ) uses.

Comments: Post a Comment

<< Home

Powered by Blogger

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