Wednesday, July 30, 2014
The Quote Parade, Part 2
Blog Entry #328
Welcome back to our discussion of the New Array Text Pages CookieQuotes.html script. Let's take stock of where we are.
Our first visit
For a first-time visit to the CookieQuotes.html page, the script prints out the quoteList[0] quote
Back Up My Hard Drive? How do I Put it in Reverse?
and adds to the CookieQuotes.html document.cookie string an ETUQuoteCount=1 cookie, meaning that we have seen one quoteList quote, per the values of the j index and the i counter; j and i are respectively set to 0 and 1 via the
i = 0; i = i % quoteList.length; j = i++;
set of operations.
We're back
For a second visit, the script increments j and i - more specifically, it extracts (the value of) i from the document.cookie string via the getCookie( ) function and an
i = parseInt(i, 10)
operation, and then copies i to j and increments i as for the first visit - and as a result prints out the quoteList[1] quoteWhat we have here is a failure to assimilate.
[Cool Hand Locutus]
and adds an ETUQuoteCount=2 cookie to the document.cookie string. And so on for subsequent visits; on our sixteenth visit,
i = i % quoteList.length;
gives 0 (as it did for our first visit) and the quote sequence begins all over again.Script checkup
Construction shmonstruction
The attentive reader may have noticed that I gave relatively short shrift to the buildArray( ) function in the previous post. Deconstruction-wise I could have said
Instantiating the buildArray object typebut I didn't. In part I didn't because we dealt with a very similar Object object creation not so long ago in the course of discussing the Java Goodies Multi-Colored Text script. But there's actually a more important reason that I glossed over the buildArray( ) function: it's excess baggage. The
The script begins by calling a buildArray( ) constructor function and passing thereto a series of quote string arguments, which are collectively given an a identifier. The a arguments are iteratively assigned to numeric buildArray properties...
var quoteList = new buildArray( ...quote strings... );
instantiation is easily converted to a dense array constructor or an array literal that doesn't require any external statements, e.g.:var quoteList = ["Back Up My Hard Drive? How do I Put it in Reverse?",
"What we have here is a failure to assimilate.<br>[Cool Hand Locutus]",
/* ...Other quotes... */
"A polar bear is a rectangular bear after a coordinate transform."];
i/j movement
For correlating i (and indirectly j) with the length of the quoteList, the
i = i % quoteList.length;
statement does the job but is too unintuitive for my taste. I prefer to compare i and quoteList.length via a simple if statement: if (i == quoteList.length) i = 0;
Incrementing the value of i (but not i itself)* in the setCookie( ) function call
setCookie("ETUQuoteCount", i + 1);
allows us to return quoteList[i] and throw j out.
*
setCookie("ETUQuoteCount", ++i);
and setCookie("ETUQuoteCount", i++);
are both problematic.(f) The former cuts quoteList[0] out of the string loop; the
document.write(quote( ));
command outputs undefined when i hits 15.(l) Even worse, the latter shuts down the quote parade altogether by holding the cookie value at 0 and therefore the display at quoteList[1].
A better cookie recipe
In the original script, the setCookie( ) function does not give the ETUQuoteCount cookie an expires value; as a result, the cookie goes up in smoke as soon as the user's browser session is over. The code below will keep the cookie around until the end of next year - that's a long enough cookie lifetime, wouldn't you say?
var myDate = new Date( );
var currentYear = myDate.getFullYear( );
myDate.setFullYear(currentYear + 1, 11, 31);
document.cookie = name + "=" + value + "; expires=" + myDate.toUTCString( );
The setFullYear( ) method of the Date object is detailed here; the toUTCString( ) method of the Date object is detailed here.
In the original script, the value of the ETUQuoteCount cookie is escape( )d when set by the setCookie( ) function and unescape( )d when extracted/returned by the getCookie( ) function. Given that the value is an integer (it doesn't contain any verboten characters) and that we're the ones setting it, however, the escape( )/unescape( ) operations are unnecessary and can be removed.
Formatting
The
document.write(quote( ));
output is marked up with h1 and center elements. Putting my imagination to work, I can see how a set of quotes could serve as a series of headings. However, if the quotes merely serve a decorative purpose, then they should be housed in a div.#quoteDiv { font-weight: bold; font-size: 32px; text-align: center; }
...
document.getElementById("quoteDiv").innerHTML = quoteList[i];
...
window.onload = quote;
...
<div id="quoteDiv"></div>
(We know from prior work that the h1 element's initial font-size is 32px.)
You are of course free to style the quoteDiv div per your preference.
Demos
I've found a couple of CookieQuotes.html demos on the Web.
(1) Demo #1 is provided by The JavaScript Source. This demo exchanges the buildArray( ) functionality for a dense array constructor**
var quoteList = new Array(
"Back Up My Hard Drive? How do I Put it in Reverse?",
"What we have here is a failure to assimilate.<br>[Cool Hand Locutus]",
... );
and doesn't give the ETUQuoteCount cookie an expires value although you can still see the script's effect by refreshing the page repeatedly.
(**Hmmm, I just noticed that the Source Code at the bottom of the CookieQuotes.html page features a dense array constructor vis-à-vis the buildArray( ) functionality.)
(2) Demo #2 comes to us courtesy of Larry "Have Camera Will Travel" Curtis. Larry holds onto the buildArray( ) functionality and gives the ETUQuoteCount cookie a 365-days lifetime.
function setCookie(name, value, days) {
var expires = new Date( );
expires.setTime(expires.getTime( ) + 1000 * 60 * 60 * 24 * days);
document.cookie = name + "=" + escape(value) + "; expires=" + expires.toGMTString( ); }
...
setCookie("ETUQuoteCount", i, 365);
The toGMTString( ) method of the Date object is deprecated, BTW. I don't like millisecond-based Date calculations and would replace the setTime( )/getTime( ) operation(s) with:
expires.setDate(expires.getDate( ) + days); // A lot simpler, huh?
We'll go through the New Array Text Pages QuoteOfTheDay.html script in the following entry.
Actually, reptile7's JavaScript blog is powered by Café La Llave. ;-)