reptile7's JavaScript blog
Monday, September 24, 2007
 
Bouncer Script A
Blog Entry #89

About a year ago, we discussed the JavaScript validation of passwords in Blog Entry #51; specifically, we used regular expressions to ensure that a user-chosen password meets certain character requirements. We return to the topic of passwords for the next few posts as we consider a set of three scripts that password-protect Web pages and that are the focus of HTML Goodies' JavaScript Script Tips #73, #74, and #75, respectively.

Each of the Script Tips #73-75 Scripts is hosted by a firewall document that stands between the user and a target Web page. Upon accessing the firewall page, the user is solicited by the script for a password and is linked to the target page if the password is correct; the user is sent to another page if the password is incorrect.

I recognize that those of you who are fully committed to the free flow of information on the Web might oppose such 'bouncer' scripts as a matter of principle, and I share your concerns. Of course, however, it would be deeply unprofessional on our part to let philosophical objections stand in the way of our analyses of these scripts, so let's get on with it, shall we? Today's entry takes up the Script Tip #73 Script, which is given below:

<script language="javascript">

var getin = prompt("What is the password?","");
if (getin == "peppermint")
{
alert("You got it! In you go...");
location.href = "scripttip73correct.html";
}
else
{
if (getin == "null")
{ location.href = "nope2.,html"; }
else
if (getin != "peppermint")
{ location.href = "nope.html"; }
}
</script>

Here's what happens when the user follows Script Tip #73's "Here's the Script" link to the scripttip73effect.html firewall/demo page:

var getin = prompt("What is the password?","");

The user is first greeted by the prompt( ) box below:

The 'What is the password?' prompt( ) box

The user types (or does not type) a password into the prompt( ) input field; after the OK or Cancel button is clicked, the prompt( ) output is assigned to the variable getin.

if (getin == "peppermint") {
alert("You got it! In you go...");
location.href = "scripttip73correct.html"; }

If the user enters peppermint, the correct password, into the prompt( ) box and clicks the OK button, then a "You got it! In you go..." alert( ) message pops up

The 'You got it! In you go...' alert( ) box

and, after the OK button on the alert( ) box is clicked, the user is taken to the scripttip73correct.html target page.

else {
if (getin == "null") { location.href = "nope2.,html"; }

This conditional is meant to come into play if the user clicks the prompt( ) box's Cancel button, in which case (and whether or not a password was typed into the input field) the primitive value null will be assigned to getin. However, like the Boolean values true and false, the null value is not quoted. For the getin == "null" condition to return true, the user must literally enter null as a string value into the prompt( ) input field and then click the OK button; I would tell you that only then is the user taken to a separate nope2.,html page, but there is in fact no nope2.,html page in HTML Goodies' /legacy/beyond/javascript/stips/ subdirectory and a "404 - File not found" page comes up instead.

And what about that comma in nope2.,html, huh? This is obviously a typo, but I nonetheless wondered, "Can you even have commas in URLs?" It turns out, somewhat to my surprise, that yes, commas can appear in URLs if and only if they are used as "sub-delimiters", e.g., for separating parameter data when they appear in a URL.

else
if (getin != "peppermint") { location.href = "nope.html"; } }

For any getin value not equal to the peppermint string (or the null string), this conditional would link the user to a nope.html page if one existed in the /legacy/beyond/javascript/stips/ subdirectory; in practice, the user is again taken to a "404 - File not found" page.

Tightening up the code

The script's 'outer' else block encompassing the if (getin == null) and if (getin != "peppermint") conditionals can be condensed to:

else {
location.href = "nope.html";
if (getin == null) location.href = "nope2.html"; }

With this formulation, the if (getin == null) conditional must appear last; otherwise, clicking the prompt( ) Cancel button will send the user to nope.html. If you'd rather route all non-peppermint getins to nope.html, however, then

else location.href = "nope.html";

is all you need.

'Defeating' the script (or not)

So, how effective of a barrier is the Script Tip #73 Script? You can see for yourself that both the peppermint password and the scripttip73correct.html target page URL appear in the script's code. Can or cannot this data be fished out of the firewall document's source?

Regarding the script's design, Joe says:
The reason [accessing the password is] difficult was the way the script was put together. None of the password elements ran before prompt or alert elements. That way it was impossible to get the page by itself without some type of JavaScript element taking the focus of the browser. The moment you'd click to lose one item - another would pop up.
At the script's demo page, I can easily put the underlying "Testing...testing...testing..." main window on top of either the prompt( ) box or the alert( ) box by
(a) first moving from the browser to another application via the application menu or by typing command-tab, and then
(b) clicking the main window's Password Required title bar
when using MSIE 5.1.6 (but not Netscape 7.02, whose response to this process was a bit strange - I'll spare you the details). Now in front, the main window nonetheless does not have "focus" - e.g., I can't highlight the "Testing...testing...testing..." with the mouse cursor and I can't change the URL in the window's address bar - but I can at least now click on the menu bar's View menu, whose Source command is grayed out:

The View menu with a grayed-out Source command

The source is unavailable because the document hasn't loaded yet. When I wrapped the script element code in a function bouncer( ) { ... } container and called the bouncer( ) function with an onload="bouncer( );" body element attribute, I was indeed able to access the document source by bringing the main window forward and going to the View menu.

There's a simpler way to try to defeat the Script Tip #73 Script, however. I go to the demo page, type peppermint into the prompt( ) box and click OK, and the alert( ) box pops up. I simultaneously position my left hand over the return key and the mouse cursor over the View menu heading at the top of the screen. On your mark...get set...go!! I hit the return key and immediately click on the View menu and go to the Source command. Lo and behold, I can consistently access the firewall document source in this way when using Netscape (but not MSIE); however, I was unable to reproduce this result when I reran the script offline on my hard disk with downloaded scripttip73effect.html and scripttip73correct.html files. Given that linking from scripttip73effect.html to scripttip73correct.html is much faster on my hard disk than on the www.htmlgoodies.com server machine, it would seem that my Netscape 'success' in defeating the script at Joe's demo page is much more reflective of the antiquity of my computer than of a reliable way to get ahold of the password.

One more thing I found out: unlike MSIE, Netscape will make a document's source available before the document has completely loaded. In my scripttip73effect.html file, I added an

<h2>This line marks the end of the document body.</h2>

element after the script element (just before the body element end-tag) and changed the if (getin == "peppermint") location to http://www.cnn.com, which loads slowly on my machine. Online and with Netscape, I am in this case again able to access the scripttip73effect.html source via the click-the-alert( )-OK-button-and-instantly-go-to-the-View-menu method described above; at no point do I ever see the This line marks the end of the document body string on the scripttip73effect.html page (it appears in the source window) before it links to CNN.com.

Spilling the beans somewhat, Joe points out that you can access the source of his own scripttip73effect.html page by
(a) right-clicking on the aforementioned "Here's the Script" link,
(b) selecting the Download Link to Disk (MSIE) or Save Link Target As... (Netscape) option and
(c) downloading the scripttip73effect.html file, and then finally
(d) opening the file with a text editor or a word processor;
of course, you couldn't do this if you were to arrive at the scripttip73effect.html page via entering its URL into the browser's address bar.

Let me wrap up this entry by answering the question I posed earlier: all in all, I would say that, notwithstanding its simplicity, the Script Tip #73 Script does a reasonably good job at password-protecting a Web page; the script does contain its password and the target Web page URL but it cleverly exploits the timing of browser/script events to hide this information most of the time.

We'll check over Script Tip #74's password-protection script in the next post.

reptile7

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

Wednesday, September 05, 2007
 
A Headline Loop
Blog Entry #87

HTML Goodies' JavaScript Script Tips #69, #70, #71, and #72 address a script that is somewhat of a cross between the slide show scripts of Primer #27 (both the go-forward main script and the go-backward assignment script) and the URL menu scripts of Script Tips #38-41. The Script Tips #69-72 Script stocks a series of "headlines" through which the user can run forwards or backwards; clicking each headline hyperlinks the user to a related resource. The Script Tips #69-72 Script can be accessed via the "Here's the Code" links in all four script tips and appears in the div below:

<head>

<style type="text/css">

</style>

<script language="javascript">

<!--

// by Leif King e-mail:leif.d.king@vanderbilt.edu
// Feel free to use this or modify it, such as making the text scroll!

// Next, Previous, Click Through Functions below 

var number = 0;
function chngNext( )
{
document.headline.shownext.value = "Y";
headMach( );
}

function chngPrev( )
{
document.headline.showprev.value = "Y";
headMach( );
}

function goTo(newURL) 
{
self.location.href = newURL;
}

// Function To Change Headline Below 

function headMach( )
{
var totalHeads = 4; //total number of headlines you want
if ((document.headline.shownext.value == "Y") && (document.headline.showprev.value == "N"))
{
var headShow = (parseInt(document.headline.nowShowing.value) + 1);
if (headShow > totalHeads)
{
var headShow = 1;}
}
if ((document.headline.showprev.value == "Y") && (document.headline.shownext.value == "N"))
{
var headShow = (parseInt(document.headline.nowShowing.value) - 1);
if (headShow < 1)
{
var headShow = totalHeads;}
}

// Links Represented by Headlines Below 

if (headShow == 1) 
{
var _head = "first headline";
var inlocat = "firstlocation.html"; 
}

if (headShow == 2) 
{
var _head = "second";
var inlocat = "secondlocation.html";
}

if (headShow == 3) 
{
var _head = "third";
var inlocat = "thirdlocation.html";
}

if (headShow == 4) 
{
var _head = "and so 4orth";
var inlocat = "fourthlocation.html";
}

document.headline.headHere.value = _head;
document.headline.nowShowing.value = headShow;
document.headline.shownext.value = "N";
document.headline.showprev.value = "N";
document.headline.inlocation = inlocat;
}
//-->

</script>

<!-- Visible HTML Below --> 

</head>
<body onload="chngNext( );">
<center>
<h2><i>Headline Linker</i></h2>
<form name="headline" method="post">
<input type="hidden" name="nowShowing" value="0">
<input type="text" name="headHere" value="Choose and Click" size="50" onclick="goTo(inlocation);"><br>
<input type="button" value="NEXT" onclick="chngNext( );">
<input type="button" value="PREV" onclick="chngPrev( );"><br>
<input type="hidden" name="shownext" value="N">
<input type="hidden" name="showprev" value="N">
</form>
</center>
</body>
</html>

Joe provides an "MSIE" script demo page here and a "Netscape" script demo page here - we'll flesh out the script's browser compatibility issues at a later point.

The headline form

At the heart of the Script Tips #69-72 Script is a form element, named headline and having an unnecessary method="post" attribute, that comprises six controls:

elements[1]: A visible text box named headHere will hold the script headlines. The headHere control is equipped with a value="Choose and Click" attribute (specified as value="**** First Choose A Headline Then Click Here ****" in the sources of the demo pages), but the user will not see the Choose and Click string, which will be overwritten by the script's headMach( ) function, as we'll see below.

elements[0]: Although the script headlines are not arrayed (they could have been), each headline has an associated 'index number' that is held by the first-in-source-order headline control, a hidden field named nowShowing and with a value attribute value initially set to 0. The script headlines are also indexed by the headMach( ) function's headShow variable; the nowShowing control is thus redundant and we'll get rid of it when we revamp the script in the next post.

elements[2], elements[3]: A NEXT push button (labeled Next Headline on the demo pages) allows the user to move forwards through the headline index; a PREV push button (labeled Previous Headline on the demo pages) allows the user to move backwards through the headline index.

elements[4], elements[5]: The headline form concludes with two hidden fields that are named shownext and showprev and are designed to act as 'on/off switches' for the NEXT/Next Headline and PREV/Previous Headline buttons, respectively; the shownext and showprev value attribute/property values accordingly toggle between N ('off') and Y ('on').

A pre-user-input deconstruction

Here's what initially happens when the user follows the "Here's the Effect" link to the "MSIE" script demo page:

<body onload="chngNext( );">

When the page has loaded, the chngNext( ) function is triggered.

var number = 0; /* This statement can be removed; the number variable does not appear subsequently in the script. */
function chngNext( ) {
document.headline.shownext.value = "Y";
headMach( ); }

The value value of the shownext field, originally set to N in the script's HTML, toggles to Y. On the following line, the headMach( ) function is triggered.

function headMach( ) {
var totalHeads = 4; // total number of headlines you want

The number of headlines stocked by the script is represented by the variable totalHeads, which is declared here. We noted in Blog Entry #44 that a slide show is a loop-like process, and you can think of totalHeads as the 'upper boundary' of the script's 'loop'.

if ((document.headline.shownext.value == "Y") && (document.headline.showprev.value == "N")) {

The shownext value value was set to Y by the chngNext( ) function - check; the showprev value value was originally set to N in the script's HTML, and is still N - check; the if condition thus returns true.

The parentheses surrounding the (document.headline.shownext.value == "Y") and (document.headline.showprev.value == "N") comparisons are unnecessary, because comparison operators have a higher precedence than do logical operators.

At no point during the script's execution do the shownext and showprev controls both read Y; consequently, the second comparison is unnecessary, and the if declaration can be shortened to:
if (document.headline.shownext.value == "Y")

var headShow = (parseInt(document.headline.nowShowing.value) + 1);
/* The outer parentheses surrounding the right side of the statement are unnecessary. */

Data-type-wise, form control values are strings. This line uses the top-level parseInt( ) function to convert the nowShowing field's value value, 0, from a string to a number (the top-level eval( ) and Number( ) functions could also have been used here); the parseInt( ) output is incremented to 1, which is assigned to the variable headShow.

(If it isn't converted to a number, the nowShowing value value will be concatenated to 1 and not added to 1, and the resulting 01 string will be assigned to headShow, which is not a problem for this run of the script but will prevent us from moving beyond the First Headline headline.)

if (headShow > totalHeads) { var headShow = 1; } }
// There is of course no need to use the var keyword for headShow a second time.

Clicking the Next Headline button four times will increment headShow to 5, at which point this conditional comes into play; until then, the headShow > totalHeads condition returns false, so the browser moves on to...

if ((document.headline.showprev.value == "Y") && (document.headline.shownext.value == "N"))
/* The if declaration can be shortened to:
if (document.headline.showprev.value == "Y") */
{ ... }

This if block will come into play when we go through the script headlines backwards. For now, both && operands return false and thus the if condition as a whole returns false, so the browser moves on to...

if (headShow == 1) {
var _head = "First Headline";
var inlocat = "firstlocation.html"; }

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

As noted earlier, headShow serves as an index number for the script's headlines. The Script Tips #69-72 Script contains four generic headlines: First Headline, Second Headline, Third Headline, and Fourth Headline; these headlines have associated headShow values of 1, 2, 3, and 4, respectively. Also associated with these headlines are resources located at firstlocation.html, secondlocation.html, thirdlocation.html, and fourthlocation.html, respectively.

Regarding the preceding if statements, the first if condition is true (headShow is equal to 1) and the other if conditions are false; consequently, First Headline is assigned to the variable _head and firstlocation.html is assigned to the variable inlocat. The browser moves to...

document.headline.headHere.value = _head;

This statement assigns the _head value, First Headline, to the value value of the headHere field, i.e., First Headline overwrites the headHere value="**** First Choose A Headline Then Click Here ****" attribute and loads into the headHere field.

document.headline.nowShowing.value = headShow;

The headShow value, 1, is assigned to the value value of the nowShowing field.

document.headline.shownext.value = "N";

The shownext field's value value, Y, toggles back to N.

document.headline.showprev.value = "N";

This statement will switch the showprev field's value value from Y to N when we go through the script headlines backwards.

document.headline.inlocation = inlocat; }

This weird statement relates to the headline-to-resource linking process, which we'll discuss when we're through with the loop part of the deconstruction.

Forward deconstruction

We are ready to move forwards through the script headlines. Clicking the Next Headline button

<input type="button" value="      Next Headline      " onclick="chngNext( );">
<!-- The spaces in the value attribute value don't add any padding to the button label (at least on my computer). -->

re-calls the chngNext( ) function and the commands above are re-executed:

(1) The shownext value value switches to Y.
(2) The headMach( ) function is called.
(3) 4 is assigned to totalHeads.
(4) The nowShowing value value is numberified and incremented to give headShow = 2.
(5) Second Headline is loaded into the headHere text box.
(6) 2 is assigned to the nowShowing value value.
(7) The shownext and showprev value values are both set to N.

Clicking again the Next Headline button loads Third Headline into the headHere field (headShow == 3); clicking again the Next Headline button loads Fourth Headline into the headHere field (headShow == 4); clicking again the Next Headline button loads First Headline into the headHere field (headShow reaches its peak value of 5 and is then reset to 1).

Backward deconstruction

Clicking the Previous Headline button

<input type="button" value="Previous Headline" onclick="chngPrev( );">

calls the script's chngPrev( ) function and a parallel set of commands is executed:

function chngPrev( ) { document.headline.showprev.value = "Y"; headMach( ); }

(1-2) The showprev value value switches to Y, and then headMach( ) is called.
(3) 4 is assigned to totalHeads.

var headShow = (parseInt(document.headline.nowShowing.value) - 1);

(4) The nowShowing value value is numberified and decremented to give headShow = 0. Use of the parseInt( ) function here is unnecessary, because for a subtraction operation, JavaScript will automatically convert the nowShowing value value to a number: see the "Data Type Conversion" section of the JavaScript 1.5 Core Guide.

if (headShow < 1) { var headShow = totalHeads; }

(5) headShow (0) is at this point less than 1, and is thus set to 4.
(6) Fourth Headline is loaded into the headHere text box.
(7) 4 is assigned to the nowShowing value value.
(8) The shownext and showprev value values are both set to N.

Clicking again the Previous Headline button loads Third Headline into the headHere field (headShow == 3); clicking again the Previous Headline button loads Second Headline into the headHere field (headShow == 2); clicking again the Previous Headline button loads First Headline into the headHere field (headShow == 1).

In the following entry, we'll hyperlink the headlines to their associated resources and also retool the script a bit.

reptile7


Powered by Blogger

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