reptile7's JavaScript blog
Friday, September 14, 2007
 
I Linked to the News Today, Oh Boy
Blog Entry #88

We continue today our analysis of the headline script of HTML Goodies' JavaScript Script Tips #69-72. At this point we've run forwards and backwards through the script's headlines and we are ready to link to the resources that they reference. We begin our discussion by returning to the headMach( ) function's last statement, which I glossed over in the previous post (and which Joe himself glosses over at the end of Script Tip #71):

document.headline.inlocation = inlocat;

This command assigns inlocat (firstlocation.html, secondlocation.html, thirdlocation.html, or fourthlocation.html) to the "inlocation" property of the headline form. We turn to the form object page of the JavaScript 1.3 Client-Side Reference; no listing for inlocation appears in the "Property Summary" table. What the script's author seems to be doing here is creating on the fly a custom form object property for holding the current inlocat value - I knew that such properties can be defined for custom JavaScript objects but I've never seen this done with a client-side or core JavaScript object. A more conventional way to store the inlocat data would be to
(a) add another hidden control to the headline form

<input type="hidden" name="inlocation" />

and (b) assign inlocat to its value value:

document.headline.inlocation.value = inlocat;

We move now to the headHere text box:

<input type="text" name="headHere" value="**** First Choose A Headline Then Click Here ****" size="50" onclick="goTo(inlocation);">

Recall that the headMach( ) function overwrites **** First Choose A Headline Then Click Here **** with the First Headline headline. So, the user clicks on First Headline (or whatever headline the user has moved to) in the headHere field, triggering the script's goTo( ) function and passing thereto the inlocation value. Given that inlocation is not a top-level property but is a property of the headline form, the goTo( ) function call should be formulated as:

onclick="goTo(this.form.inlocation);"
or
onclick="goTo(document.headline.inlocation);"

(We've seen this sort of thing once before: in the frames layout script of Script Tips #49-51, we encountered a Clear All push button that executed a reset( ) command without referencing the parent form.)

function goTo(newURL) {
self.location.href = newURL; }
// The statement above can be shortened to: location = newURL;

In the goTo( ) declaration, the inlocation parameter is renamed newURL, which is subsequently assigned to self.location.href, triggering a link to the newURL/inlocation resource.

Browser compatibility issues

(1) To the heads of the demo page documents, Joe adds a

<style type="text/css">
<!--
input { cursor: hand; }
-->
</style>

style element that sets the value of the CSS cursor property to hand to help the user recognize that the headHere headlines are also hyperlinks. Contra HTML Goodies' "CSS and Cursors" tutorial, hand is not a "standard" (W3C-approved) value for the cursor property; rather, hand is a proprietary, MSIE-specific cursor property value. On the demo pages, my mouse cursor accordingly changes into a little hand over the headHere text box and the Next Headline/Previous Headline buttons when using MSIE, whereas I see an auto cursor (auto is the "initial" cursor value) over these controls when using Netscape (specifically, I see a text cursor (an I-bar) over the headHere field and a default cursor (an arrow pointing towards 11 o'clock) over the Next Headline/Previous Headline buttons).

A slight modification leads to a cross-browser solution: I find that an input { cursor: pointer; } style rule gives a hand cursor over the headline controls when using either MSIE or Netscape.

(2) The W3C specifies that onclick is a valid attribute for the input element, as does the MSDN Library. At the time the Script Tips #69-72 Script was written, however, JavaScript (read: Netscape) supported the onClick event handler for the button, submit, reset, radio, and checkbox objects but not for the text object. Consequently, Joe created a separate "Netscape" script demo page that uses a

<input type="button" value="Click to Go!" onclick="goTo(inlocation);">

button to trigger the goTo( ) function. Joe could have stuck with the headHere field had he equipped it with an onFocus="goTo(inlocation);" function call instead. Anyway, I can confirm that modern versions of Netscape (Netscape 7.02 in my case) now support onclick for the text object and will link a clicked headHere headline to its associated resource on Joe's "MSIE" script demo page.

Streamlining the Script Tips #69-72 Script

So, what was new about the Script Tips #69-72 Script, huh? Did we learn anything? The script's novel feature is its use of hidden controls to store values generated by the headMach( ) function. The

document.headline.nowShowing.value = headShow;
document.headline.shownext.value = "N";
document.headline.showprev.value = "N";

headMach( ) commands are somewhat like return statements but are arguably a bit more flexible in that their exported values are not sent to specific points on the page. I would have discussed this in my introduction for the previous post were it not for the fact that the script's hidden controls are actually unnecessary, as are the script's chngNext( ), chngPrev( ), and goTo( ) functions, for that matter. The script's document body HTML can be shrunk to:

<body onload="headMach('forward');">
<h2 class="ita">Headline Linker</h2>
<span class="ita">Choose a headline, then click on it.</span>
<form name="headline">
<input name="headHere" size="50" onclick="location=this.form.inlocation;" /><br />
<input type="button" name="forward" value="Next Headline" onclick="headMach(this.name);" />
<input type="button" name="backward" value="Previous Headline" onclick="headMach(this.name);" />
</form></body>

Note that the Next Headline and Previous Headline buttons have been named forward and backward, respectively.

Here's the accompanying CSS:

body { text-align: center; }
.ita { font-style: italic; }
input { cursor: pointer; }

The content of the script's script element can now be recast as:

var headShow = 0, totalHeads = 4, _head, inlocat;
function headMach(buttonname) {

if (buttonname == "forward") {
headShow++;
if (headShow > totalHeads) headShow = 1; }

if (buttonname == "backward") {
headShow--;
if (headShow < 1) headShow = totalHeads; }

if (headShow == 1) { _head = "First Headline"; inlocat = "firstlocation.html"; }
if (headShow == 2) { _head = "Second Headline"; inlocat = "secondlocation.html"; }
if (headShow == 3) { _head = "Third Headline"; inlocat = "thirdlocation.html"; }
if (headShow == 4) { _head = "Fourth Headline"; inlocat = "fourthlocation.html"; }

document.headline.headHere.value = _head;
document.headline.inlocation = inlocat; }

To make the document XHTML-compliant, put the script element content, which contains an offending < character, in a separate headline_script.js file and call it in the document head with:

<script type="text/javascript" src="headline_script.js"></script>

Please choose a headline

At the beginning of Script Tip #69, Joe lists several changes that he made to the Script Tips #69-72 Script in its original form. We've addressed his Change #2 (generating a hand cursor over the headHere headlines) and Change #4 (making the script work with Netscape) but not his Changes #1 and #3:
1. The script had a random button which didn't work very well. I took it out.
3. The original script required the user to click on a button before choosing a headline. If the user clicked on the text box without first choosing a headline, the script would throw an error. I fixed that.
I'll show you how to randomize the headHere headlines in the next section. Regarding Change #3, Joe "fixed" the click-on-Choose and Click-and-get-an-error problem by overwriting Choose and Click with the First Headline headline, but let's suppose that you do want the user to see the Choose and Click string when the page loads. To the script element content of the streamlined code above, let's add a new-and-improved goTo( ) function:

function goTo( ) {
if (headShow == 0) window.alert("Please choose a headline.");
else location = document.headline.inlocation; }

Then, let's remove the onload="headMach('forward');" function call from the body element start-tag (i.e., simply code it as <body>) and recode the headHere field as:

<input name="headHere" size="50" value="Choose and Click" onclick="goTo( );" />

Ta-da! If the user clicks on Choose and Click, then a "Please choose a headline" alert( ) message pops up - no errors.

A random headline

This is a bit more involved but not at all difficult. First, let's parallel-array the headlines and their resources:

var hline = new Array( );
hline[1] = "First Headline";
hline[2] = "Second Headline";
hline[3] = "Third Headline";
hline[4] = "Fourth Headline";

var hlineURL = new Array( );
hlineURL[1] = "firstlocation.html";
hlineURL[2] = "secondlocation.html";
hlineURL[3] = "thirdlocation.html";
hlineURL[4] = "fourthlocation.html";

The headMach( ) function can now be condensed to:

var headShow = 0, totalHeads = 4;
function headMach(buttonname) {

if (buttonname == "forward") { headShow++; if (headShow > totalHeads) headShow = 1; }
if (buttonname == "backward") { headShow--; if (headShow < 1) headShow = totalHeads; }

document.headline.headHere.value = hline[headShow];
document.headline.inlocation = hlineURL[headShow]; }

We next add a Click Here for a Random Headline button to the headline form:

<input type="button" value="Click Here for a Random Headline" onclick="randomhline( );" />

When clicked, this button will call the following function:

function randomhline( ) {
headShow2 = Math.ceil(4 * Math.random( ));
document.headline.headHere.value = hline[headShow2];
document.headline.inlocation = hlineURL[headShow2]; }

The random headline, hline[headShow2], can be hyperlinked to its resource, hlineURL[headShow2], by the previous section's goTo( ) function.

Does this approach look familiar? It should - it borrows heavily from the random banner script of Script Tip #34.

A scrolling headline

The script's author, Leif King, invites us to use [the script] or modify it, such as making the text scroll! Your assignment, if you choose to accept it, is to make the headHere headlines scroll via the methodology of the Script Tips #35-37 Script.

Script Tips #73, #74, and #75 respectively cover a 'trilogy' of scripts that password-protect Web pages. None of these scripts is very complicated and we'll sail right through them...or will we? In any case, we'll look at the Script Tip #73 Script in the next entry.

reptile7

Comments: Post a Comment

<< Home

Powered by Blogger

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