reptile7's JavaScript blog
Wednesday, December 28, 2005
 
Opening New Windows, Part 1
Blog Entry #25

You may know that opening an HTML link in a new browser window is a simple matter of putting target="resource window" in the anchor tag, e.g.:

Click <a href="http://www.yahoo.com" target="resource window">here</a> to open the Yahoo! portal in a new window.

Click here to open the Yahoo! portal in a new window.

HTML Goodies usefully provides a tutorial on this very topic here. Alternately, Blogger.com notes in its "How can I do more with links" Help topic that target="_blank" can also be used in the anchor tag for this purpose. HTML Goodies' JavaScript Primers #11 and #12, which we'll go over in the next few posts, discuss the JavaScript version of this process enabled by the open( ) method of the window object. As we'll see, JavaScript allows considerably more control over the opening of new windows than do the target="resource window" and target="_blank" methods cited above.

Moreover, HTML Goodies' Beyond HTML : JavaScript section sports an "Opening New Windows With JavaScript" collection of tutorials. I am hesitant to recommend these tutorials, because several of the scripts therein are either 'problematic' (read: on my computer, they don't work as advertised), or are, IMO, pointlessly complicated. However, I'll try to address most of the issues they raise in either this or the next blog entry.

The window.open( ) command: loading a file (or not) into a newly opened window

A new browser window is straightforwardly opened with a window.open( ) command statement, which can be executed either by normal placement in a script (as is done in the Primer #11 Script) or by assignment to an appropriate event handler, e.g.:

Move your mouse over <span style="color:red;" onmouseover="window.open( );">these words</span> to open a new window.

Move your mouse over these words to open a new window.

The code above opens a new, blank window with the same width and height as the preexisting window that holds the document containing the code. Positionwise, the new window is on top of the preexisting window and is 'currently active,' i.e., the new window has 'focus,' whereas the preexisting window is now 'blurred'; also, the new window is slightly offset (lower and to the right or left) from the preexisting window. The features of the new window are browser-dependent: with Netscape, the new window has all of the 'bars' - a title bar (reading "Netscape"), an address bar, a status bar, etc. - of the preexisting window, but with MSIE, all you get is a title bar (reading "about:blank").

But blank windows aren't very exciting, are they? We can load another document into the new window by putting a first, URL-specifying parameter in the instance of the open( ) method, e.g.:

Move your mouse over <span style="color:green;" onmouseover="window.open('http://www.google.com');">these words</span> to open the Google home page in a new window.

Move your mouse over these words to open the Google home page in a new window.

Commands that return URLs are also suitable open( ) parameters; the script below:

<script type="text/javascript">
window.open(window.location);
</script>

will (re-)open the current document in a new window.

We are not limited to HTML-type documents in this regard; for example, an image can also be loaded into a new window:

Move your mouse over these words to open a new window containing a photo of Alli, the sleeping kitty.

Move your mouse over <span style="color:blue;" onmouseover="window.open('https://3.bp.blogspot.com/-pO9mHpHaa8Q/Vy-BF2ilTrI/AAAAAAAAAjw/AJTPNGfxrLsB6z1tSNWU4b7jBUkrtnfggCLcB/s1600/Alli.jpg');">these words</span> to open a new window containing a photo of Alli, the sleeping kitty.

Now, if all you want to do is open and display a file in a normal-sized window, then you're done - the window.open("http://www.some_web_page.com") syntax is all you need. However, two additional open( ) parameters will allow us (a) to configure a newly opened window, specifically, to set its width/height and to add/subtract its various components, and (b) to 'communicate' between the new and preexisting windows. Let's look at these parameters, shall we?

Naming a new (or preexisting) window

The URL in the open( ) instance can be followed by a second parameter that is earmarked for assigning a name to the new window:

window.open("http://www.some_web_page.com", "new_window_name");

More precisely, the second open( ) parameter sets the value of the name property of a newly created window object. The "new_window_name" text string cannot be used to reference the new window in the manner of the "self," "parent," and "top" properties of the window object; rather, as we'll see later, "new_window_name" is used to target 'output' to the new window from the preexisting window or from other, subsequently opened new windows.

While I'm on this topic, I should mention that we can name the preexisting window for targeting purposes with a simple

window.name = "whatever";*

command statement placed normally in a script.

(*Perhaps I shouldn't say "whatever" - like JavaScript variables, window names cannot contain whitespace nor nonalphanumeric (!, @, #, etc.) characters.)

Configuring a new window

The name in the open( ) instance can be followed by a third parameter that configures the new window:

window.open("http://www.some_web_page.com", "new_window_name", "new_window_features");

In using the third open( ) parameter, the name parameter is not optional, but can be 'left blank,' as follows:

window.open("http://www.some_web_page.com", "", "new_window_features");

With respect to the preceding command, on my computer...
(1) Leaving out the empty quotes of the name parameter:
window.open("http://www.some_web_page.com", "new_window_features");
generates a "Type mismatch" error (classified by Microsoft here as a syntax error but (this resource is no longer available, and may have been relevant to a different technology) by my computer as a runtime error) when using MSIE; with Netscape, the new window still opens, but the "new_window_features" parameter is ignored.
(2) Putting whitespace between the empty quotes of the name parameter:
window.open("http://www.some_web_page.com", "    ", "new_window_features");
also generates a "Type mismatch" error when using MSIE; in this case, Netscape executes the command without incident.

Looking at various Web sites, I count a total of 32 configurable features, many of them Netscape-specific* and some of them deprecated, associated with the third open( ) parameter. (*Recall from Blog Entry #18 that many window object properties are Netscape-specific.) Kudos to Gérard Talbot, who lists and details browser support for all but one of these features here (he's missing the MSIE-specific channelmode feature, which is discussed here by JavaScript Kit). HTML Goodies, for its part, covers in Primer #11 the following nine new window features, all of which are supported by both MSIE and Netscape:

width, height, toolbar, menubar, scrollbars, resizable, location, directories, status

Some comments on these features:

(1) We can easily set the width and height, in pixels, of a newly opened window, e.g.:

"width=700, height=200"

Paralleling the use of width and height attributes in an <img> tag, the "700" and "200" values above do not need to be followed by the "px" unit identifier. My attempts to set the dimensions of a new window with other units - I specifically tried width/height lengths in points (pt), centimeters (cm), inches (in), and percentages (%), which are all OK for use with the CSS positioning width and height properties - were unsuccessful.

(2) The other seven features are Boolean: setting them to "yes", or "1", or simply listing them will (depending on the user's platform) 'turn them on.' I find that I can also enable these features by setting them to "true" when using MSIE but not Netscape.

At its window.open( ) page, DevGuru notes: "[I]f you don't supply any of the feature arguments, all features with a choice of yes or no are enabled"; on my computer, this is true when using Netscape, but not MSIE, which does not enable features that are not listed, this being consistent with my above observations on the browser-dependent features of newly opened blank windows. DevGuru continues: "[I]f you do specify any feature parameters...all [unspecified] others are no" - this is true for both browsers.

(3) When the toolbar feature is activated, MSIE installs a Button Bar;


with Netscape, this subset


of the Navigation Toolbar


is visualized.

(4) In the "Parts of a Window" section of Blog Entry #18, I remarked, "[O]n my iMac, the browser menubar is not part of the window but is separate therefrom, and setting window.menubar.visible=false has no effect"; conversely, I find that I cannot add a new menubar to a new window via the menubar feature above.

(5) Turning on the scrollbars feature gives a right scrollbar IF the vertical length of the document in the new window exceeds that of the new window (there's no scrollbar if the entire document can be seen in the window). On the other hand, if the horizontal length of the new window's document exceeds that of the new window, then a listed scrollbars feature does not install a bottom scrollbar; rather, the document content is scrunched to the left so that it fits in the new window.

(6) When the location feature is activated, MSIE installs an Address Bar;


with Netscape, this part


of the Navigation Toolbar is visualized.

(7) When using Netscape, turning on the directories feature renders the Personal Toolbar;


relatedly, Mr. Talbot's site notes that there is a Netscape-specific personalbar feature that does the same thing. However, QuirksMode.org reveals at its "Popups" page that the directories feature is not supported by MSIE 5.2 for the Macintosh; sure enough, I find with MSIE that a listed directories feature does not add a Favorites Bar (below the Address Bar)


or any other bar to a new window, but has no effect.

I don't need to go over the resizable (allows window resizing) and status (gives a status bar) features, do I? Didn't think so.

Time to put it all together - Joe gives us the following syntax, taken from his answer to the Primer #11 Assignment, for the third open( ) parameter:

config='height=100,width=400,toolbar=no,menubar=yes,scrollbars=no,resizable=no,location=no,directories=yes,status=no'

The "config=" part at the beginning is unnecessary, and I have no idea where it comes from...it doesn't appear in any of Netscape's JavaScript reference material (not even in JavaScript 1.0, the first version of the language), DevGuru doesn't use it, JavaScript Kit doesn't use it, Microsoft's reference material doesn't mention it, Joe himself doesn't use it in the Primer #12 Script. Leave it out.

As shown above, the new window features are separated by commas; when I tried to delimit them with semicolons, à la successive style properties, the results were browser-dependent and also dependent on the feature sequence, and I'm not sure it's worth it to go into the details thereof, so let's just say stick with commas here.

Joe emphasizes a couple of times - the first time in red text, no less - that there shouldn't be any whitespace in the "new_window_features" string. However, I find that whitespace is allowable between successive features, but not within an individual feature, when using either MSIE or Netscape, e.g., "height=100, width=400" is OK, but "height = 100, width = 400" will be ignored by the browser.

From a practical standpoint, then, the window.open( ) command in Joe's assignment answer could be steamlined as:

window.open ('opened2.html', 'newwin', 'height=100, width=400, menubar, directories')

(Yes, I know that Joe asks the reader to use "every one of those features" in the assignment - better to enable them all, IMO.)

There are two other new window features that are supported by both MSIE and Netscape: left and top, which position respectively the left and top borders of the new window from the left and top boundaries of the monitor screen in the same way that the screenX/screenLeft and screenY/screenTop properties of the window object would apply to positioning the preexisting window. Like the width and height features, the left and top features are specified in pixels, without units.

Finally, Joe informs us that a newly opened window necessarily has a title bar - "You get it, like it or not," he says, and he's largely but not completely correct. As noted by DevGuru and by Mr. Talbot, there is a Netscape-specific titlebar feature, and in its JavaScript 1.3 Client-Side Reference, Netscape reports, "To set the titlebar to no, set this feature in a signed script," which seems to me, after glancing over Netscape's documentation on signed scripts, way more trouble than it's worth just to get rid of the title bar.

As for MSIE, the "Opening New Windows With JavaScript" sector of HTML Goodies, linked at the outset of this post, features a "New Window: No Title Bar" tutorial with a script that Joe claims will open a new window without a title bar when using MSIE. The script's highlight is the MSIE-specific fullscreen feature (Joe wrongly insinuates that the fullscreen feature is supported by both MSIE and Netscape), which, in theory, gives when enabled a window that fills the entire monitor screen; however, Mr. Talbot links here to a Microsoft Windows XP site that states, "When creating a window, the definition of the fullscreen=yes specification is changed to mean 'show the window as maximized,' which will keep the title bar, address bar, and status bar visible." In the event, my own trial run with the fullscreen feature afforded a window with a title bar, but no other bars, and with the same width and height as the preexisting window (regardless of its size).

BTW, if for some reason you do want a new window to fill the user's screen, then this can be done more reliably with the following code:

window.open("http://www.some_web_page.com", "", "width=" + screen.width + ", height=" + screen.height);

in which the width and height properties of the screen object, representing the user's monitor screen, are returned and assigned respectively to the width and height new window features.

OK, these are the basics of opening new windows. However, we're not done yet with Primer #11; still on the board for discussion are methods for window-window communication, which we'll get to in the next entry.

reptile7

Monday, December 12, 2005
 
Event Handlers, Act IV
Blog Entry #24

The HTML Goodies JavaScript Primers series turns its gaze one more time to event handlers in Primer #10, in which it discusses the onMouseOut and onUnload event handlers. To review briefly: HTML Goodies introduced a first event handler, onMouseOver, in Primer #4, and then covered in Primer #5 several additional event handlers (onClick, onFocus, etc.). Joe Burns treats onMouseOut and onUnload together in Primer #10 "because they act after the fact"; what he means by this is that the mouseout and unload events are not 'standalone,' but require a previous event to have occurred, specifically, a mouseout event necessarily follows a mouseover event, and an unload event necessarily follows a load event. Other "after the fact" event handlers include the onBlur, onKeyUp, and onMouseUp event handlers, which we will briefly consider at the end of this entry.

(In light of our discussion of the DOM in Blog Entry #22, let me point out, in the name of completeness, that "[t]he set of all events which may occur, and the particular page elements on which they can occur, is part of the Document Object Model (DOM), and not JavaScript itself," to quote WDVL.)

onMouseOut

As its name implies, the onMouseOut event handler executes JavaScript code in response to moving the mouse cursor out/away from a 'mouseovered' document body element. This versatile event handler can be applied to:

(1) Text

I am a chameleon.

<span onmouseover="this.style.color='red';" onmouseout="this.style.color='green';">I am a chameleon.</span>

(Contra Primer #10, event handlers are not case-sensitive, as we noted in Blog Entry #7.)

(2) Form controls
(Depending on your browser, you may need to click the text box below to start the effect(s).)

Tell us your first name, please:

<form>
Tell us your first name, please: <input size="40" onmouseover="this.value='Just click and enter your name...';" onmouseout="this.value='Don\'t be shy...';">
</form>

(3) Images


<img width="430" height="330" src="https://1.bp.blogspot.com/-YjQMsVB1bsI/Vy4wgMId2tI/AAAAAAAAAiI/OG1wxMsPcvwb7mkoWU9vVMPpY5lthsjqgCLcB/s1600/tricat.jpg" onmouseout="window.alert('Feed us!');">

(4) Tables and elements thereof

   
   
   

Click here for the code.

I leave it to you, as the list above is not meant to be complete, to apply onMouseOut to other document elements. (FWIW, my attempts to use either onMouseOver or onMouseOut with an "in-line frame" were unsuccessful.)

The Primer #10 Script

Joe for his part uses the onMouseOut event handler in the Primer #10 Script, appearing below, with a hyperlink (as he did onMouseOver in the Primer #4 Script):

<BODY onUnload="alert('Leaving so soon?')">
<A HREF="Unloadpage.html" onMouseOver="window.status='Hey! Get off of me!';
return true" onMouseOut="window.status='Much better - Thanks'; return true">
Place your mouse on and off of this</A>

In the "Deconstructing the Script" section of Primer #10, Joe asks, "Remember a few primers back when we separated two Event Handlers with a comma so they would occur simultaneously?" He is referring here to the code below, culled from the "But I Want Both Effects" subsection of Primer #4:

<A HREF="http://www.htmlgoodies.com"
onMouseOver="document.bgColor='pink',
onMouseOver=window.status='Go to the Goodies Home Page';
return true">Click Here</A>

Because the document.bgColor and window.status commands above are triggered by the same mouseover event, however, a single onMouseOver event handler attribute can be used to execute both commands, as noted in Blog Entry #7. Joe emphasizes that mouseover and mouseout are distinct events that thus require separate event handlers, which should be obvious from my demos above.

We also discussed the use of the "return true" statement with the onMouseOver event handler in some detail in Blog Entry #7. To recap: I found on my computer that "return true" (a) must follow onMouseOver in an anchor tag when using Netscape but (b) is unnecessary under other circumstances (e.g., when onMouseOver is used with other tags, or when using MSIE). I similarly find that it is unnecessary to follow the onMouseOut event handler with "return true", whether in an anchor or nonanchor tag and whether using Netscape or MSIE, which makes sense, because there is no 'default HTML behavior' to preempt in moving the mouse cursor away from a link or other element.

We discussed and demonstrated the onUnload event handler in Blog Entry #10, using it there with the alert( ) method, as Joe does above.

The Primer #10 Assignment

Like the Primer #10 Script, the Primer #10 Assignment asks the reader to use the onMouseOut and onMouseOver event handlers with a link to execute window.status commands, which, in the assignment answer, incorporate navigator.appName and document.location commands that are returned and then concatenated with text strings to make up the status bar messages:

<a href="assign_10.html" onMouseOver="window.status='Hey ' + navigator.appName + ' user - click here!'; return true" onMouseOut="window.status='You should leave ' + document.location + ' right away.'; return true">Run your mouse over this link</a>

(Recall the Primer #3 Script, in which Date( ) object methods are similarly returned in the instance of a document.write( ) command.)

Joe rightfully calls attention to the quote formatting of the anchor tag above; note that navigator.appName and document.location appear outside the single quotes of the window.status values but inside the double quotes of the onMouseOver or onMouseOut value. Actually, the "Other code possibilities..." section of my previous blog entry features onLoad commands in <body> tags that incorporate variables in an analogous way, but I negligently did not comment on the quote formatting of those commands.

In the assignment answer, an onUnload event handler is used to trigger the goodbyedate( ) function comprising five now-familiar commands. When using onUnload to call a function, an alternate syntax is possible; instead of putting onUnload="goodbyedate( )" in the <body> tag, we could modify the script in the document head as follows:

// after the first four goodbyedate( ) commands:
alert("Leaving so soon? It's only " + t + ".");
}
window.onunload = goodbyedate;
// end hiding --> etc.

In the code above, note that goodbyedate is not followed by a set of parentheses; the browser treats:

window.onunload = goodbyedate( );

as a normal function call, and the goodbyedate( ) function fires when the page loads (and does not fire when the page unloads), or at least that's what happens on my computer. Also note that goodbyedate; is not put in quotes; were you to do so, the goodbyedate( ) function will not fire at all when the page either loads or unloads.

(And yes, there is an analogous window.onload = function_name; syntax for calling a function when a page loads.)

Let me lastly note that Joe's answer, as 'shaped' on the answer page, contains an error that prevents the script in the answer from running, namely:

<!-- Hide from browsers that do
    not understand Javascript

should not be split between two lines, but all on one line (Joe makes this point in Primer #9), as it is in the page's source.

Other 'After-the-Fact' Event Handlers

(1) The onBlur event handler executes JavaScript code in response to a blur event, which necessarily follows a focus event. We discussed and demonstrated the onBlur event handler here in Blog Entry #9.

(2) The onKeyUp event handler executes JavaScript code in response to a keyup event, which "occurs when the user releases a [keyboard] key from its depressed position," to quote DevGuru, and which necessarily follows a keydown or keypress event (these events have their own event handlers, onKeyDown and onKeyPress). In illustration, type in lowercase letters your favorite color in the text box below:

Shout out your favorite color:

The code for this is:
<form>
Shout out your favorite color: <input onkeyup="this.value=this.value.toUpperCase( );">
</form>

The demo above, which was inspired by the example on DevGuru's onKeyUp page, makes use of the toUpperCase( ) method of the JavaScript String object; we noted in Blog Entry #22 that the values of field-type form controls function as String objects.

(3) The onMouseUp event handler executes JavaScript code in response to a mouseup event, which occurs "whenever the user releases the mouse button," again quoting DevGuru, and which necessarily follows a mousedown event (there is a corresponding onMouseDown event handler). There is little, if any, practical difference between the onMouseUp and onClick event handlers - to the best of my knowledge, onMouseUp and onClick can be used with the same document body objects, including the document itself - but let's illustrate onMouseUp anyway, why not? Click on the Submit button below to see an onMouseUp command in action:


The code for this is:
<form>
<input type="button" value="Submit" onmouseup="this.value='Thanks for filling out the form.';">
</form>

(4) Looking over DevGuru's list of event handlers, I was curious as to whether the onDblClick event handler, which executes JavaScript code in response to double-clicking the mouse button, might also be an "after the fact" event handler, as it seemed to me that a dblclick event would necessarily follow a click event. However, unlike the pairs of events discussed previously in this post, I find that I cannot separate the dblclick event from the click event. Consider the code below:

Click <a href="http://www.google.com" onclick="window.alert('Let\'s get searching, shall we?');" ondblclick="window.alert('Ouch! One click is enough, thank you very much!');">here</a> to go to the Google home page.

Click here to go to the Google home page.

Double-clicking the word "here" executes the onClick command, but not the onDblClick command.
(FYI: contra DevGuru, onDblClick is supported by Netscape as well as by MSIE; contra Netscape, onDblClick is indeed implemented on the Macintosh.)

I may or may not craft another entry before the end of the year, as I'm thinking of acting on my long-held plans to upgrade my computer in the next week or two, which will result in some 'downtime' vis-à-vis my blogging efforts...in any case, we will in the next post look at HTML Goodies' JavaScript Primers #11, which discusses a classic JavaScript-driven process: opening new browser windows on command.

reptile7

Thursday, December 01, 2005
 
Introduction to JavaScript Functions
Blog Entry #23

In my very first blog entry, I drew a parallel between JavaScript and elementary algebra, noting, inter alia, "If you are comfortable with the concepts of variables and functions, both of which crop up in JavaScript, then you, too, may find JavaScript to be your cup of tea." Having discussed variables in JavaScript in Blog Entry #5, we turn our attention today to JavaScript functions, which are treated introductorily in HTML Goodies' JavaScript Primers #9. Certainly, many of the command statements that we have seen thus far can fairly be considered functions in that they map an "input" onto a unique "output". For example:

document.bgColor = "blue";

maps the input "blue" onto the bluing of a document's background color. And:

location.href = "http://www.htmlgoodies.com";

maps "http://www.htmlgoodies.com" onto a linking to the HTML Goodies home page. In the programming world, a function, a.k.a. a subroutine, has a somewhat more specific definition:

"...a sequence of code that performs a specific task, as part of a larger program, and is grouped as one or more statement blocks..."

to quote Wikipedia. And at least as far as JavaScript is concerned, JavaScript Kit, in its "Functions and creating your own functions" tutorial, helpfully adds:

"Functions...are not executed until you call upon them. It's like your trusted car - it can take you places, but it only does that when you drive it - it does not start driving by itself."

HTML Goodies, in turn, states:

"A function is similar to assigning a variable name to the output of a Javascript command line. What you are doing is assigning a name to an event or a series of events so that you can call on those events by that one function name rather than rewriting the commands over and over again."

Functions are rather integral to JavaScript, as will become clear as we continue to work our way through the HTML Goodies JavaScript primers.

Function Syntax

JavaScript functions can be declared in two ways:

(1) Via a function statement, as follows:

<script type="text/javascript">
function function_name( )
{
command_statement_A;
command_statement_B; etc.
}
</script>

Before going any further, let's get straight the correct names of the various punctuating enclosure marks:

{ } are braces
[ ] are square brackets
< > are angle brackets
( ) are parentheses

In the script above, function_name is in effect a variable that identifies the function; the rules for naming JavaScript functions are thus the same as are those for naming JavaScript variables, as you might expect.

At the end of my previous blog entry, I described a JavaScript function as "an extension of the method concept"; like many methods, function_name( ) can have parameters, as we'll see in future primers.

The braces that delimit the command statements of the function do not need to be on their own lines. For the first line of the function, for example, we could (and most scriptwriters would) have written:

function function_name( ) {

As far as I am aware, there is, at least in theory, no limit to the number of command statements that a function can hold.

(2) Less frequently, a function is declared via a constructor statement, as follows:

<script type="text/javascript">
var function_name = new Function("command_statement_A; command_statement_B; etc.");
// Note the quotes around the command statements; they're necessary.
</script>

As noted in the "Placement of these Items" subsection of Primer #9, a function-containing script is typically placed in the document head, allowing the function to load into the user's RAM before it might be executed.

Executing a Function

As noted above, a function block of command statements does not run by itself, but is "called", often by:

(1) "Simply...specifying its name followed by a parenthetical list of arguments, if any," as noted by WDVL and also by the JavaScript Kit tutorial linked above (but, strangely, not by HTML Goodies), i.e.:

function_name( );

This statement can appear in the same script that holds the function, or in a subsequent script.

(2) The function_name( ); statement above can be assigned to a suitable event handler, e.g.:

<form>
<input type="button" value="Click here to call the function." onclick="function_name( );">
</form>

The Primer #9 Script

Let's now look at the Primer #9 Script and the function it contains:

<head>
<script type="text/javascript">
<!-- Hide from browsers that do not understand Javascript

function dateinbar( )
{
var d = new Date( );
var y = d.getFullYear( );
var m = d.getMonth( ) + 1;
var d = d.getDate( );
var t = m + '/' + d + '/' + y + ' ';
defaultStatus = "You arrived at the page on " + t + ".";
}

// End hiding -->
</script>
</head>

<body bgcolor="ffffcc" onLoad="dateinbar( )">

As you can see, the dateinbar( ) function is triggered by an onLoad event handler, which we discussed (and demonstrated) in Blog Entry #10.

Joe discusses in some detail the HTML-commenting-out of the dateinbar( ) function for non-JavaScript-capable browsers in the "Hey! What are those <!-- and --> things up there?" subsection of Primer #9, even as the gist of this information has appeared in the "Comments" entry on the "Click Here For What You've Learned" page linked at the bottom of each primer as far back as Primer #3. At first glance, one is inclined to think, "Man, this material is seriously out of date; anyone out there using a non-JavaScript-capable browser needs to do some major upgrading," but perhaps it has some value as an 'historical aside'. In any case, we for our part discussed various modes of commenting in Blog Entry #6.

If the command statements in the dateinbar( ) function look familiar, they should - the first five of them are taken, 'verbatim', from the Primer #6 assignment, so there's no need to review them here. With respect to the last command:

defaultStatus = "You arrived at the page on " + t + ".";

I hashed over the execution of window.defaultStatus and window.status commands on my computer in the "Window Status, revisited" section of Blog Entry #18. Contra Primer #9, a window.status command does not need to be paired with an event handler, and can indeed be used in place of a window.defaultStatus command IF there are no other window.status commands in the document to override it.

Other code possibilities...

(1) You may be wondering, "Is it really necessary to use a function here?" Not at all, it must be confessed. On my computer, I find that I can (a) comment out the function dateinbar( ), {, and } lines, (b) leave the first five dateinbar( ) commands where they are, and then (c) replace onLoad="dateinbar( )" in the <body> tag with:

onLoad="defaultStatus = 'You arrived at the page on ' + t + '.' ;"

to reproduce the script's effect when using either MSIE or Netscape. (With Netscape but not MSIE, I can alternatively (a) comment out the function dateinbar( ), {, and } lines, (b) leave all six dateinbar( ) commands where they are, and then (c) delete onLoad="dateinbar( )" in the <body> tag. As noted in the "Window Status, revisited" discussion linked above, it's my experience that MSIE is 'fussier' than Netscape vis-à-vis writing status bar messages.) In addition and more awkwardly, assigning all six function commands to the onLoad event handler will also work:

<body bgcolor="ffffcc" onload="var d = new Date( ); var y = d.getFullYear( ); var m = d.getMonth( ) + 1; var d = d.getDate( ); var t = m + '/' + d + '/' + y + ' '; defaultStatus = 'You arrived at the page on ' + t + '.' ;">

(2) Joe declares the dateinbar( ) function conventionally with a function statement, but he could have used a constructor statement:

var dateinbar = new Function ("var d = new Date( ); var y = d.getFullYear( ); var m = d.getMonth( ) + 1; var d = d.getDate( ); var t = m + '/' + d + '/' + y + ' '; defaultStatus = 'You arrived at the page on ' + t + '.' ;");

(Doesn't look quite as nice, does it?)
This function can also be triggered by the onLoad="dateinbar( )" event handler.

(3) On my computer, the dateinbar( ) function can be executed by a simple dateinbar( ); statement, i.e.:

dateinbar( );
// In the source code, this would be placed outside, and subsequent to, the function.

when using Netscape but not MSIE, regardless of whether the statement is in the document head or body. (Once again, with MSIE I am only able to write the window defaultStatus or status property via an event handler.)

Function Returns

A function is often designed to direct its 'output' to code elsewhere in the document; this is straightforwardly accomplished via an appropriate return statement. Consider the modification of the Primer #9 Script shown below:

// After the first five commands of the dateinbar( ) function, we write:
defaultStatus = "You arrived at the page on " + t + ".";
return defaultStatus;
}
document.write(dateinbar( ));
// End hiding --> etc.

What happens is that the document.write(dateinbar( )); command triggers the dateinbar( ) function, whose concluding return defaultStatus; statement sends the value of defaultStatus ("You arrived at the page on " + t + ".") back to the document.write(dateinbar( )); command, which then writes the defaultStatus value to the page display. Importantly, we see in the code above that JavaScript functions can be called from within other JavaScript expressions. Function returns will crop up on several occasions when we work our way through the HTML Goodies JavaScript Script Tips.

The Primer #9 Assignment

Let's turn now to the Primer #9 Assignment, in which Joe asks the reader to 'functionize' a series of commands that outputs a greeting to the user. Here are a few points that I would make about Joe's "possible answer" thereto:

(1) We discussed the syntax for the prompt( ) method of the window object in Blog Entry #11; as noted there, if you're not going to put anything in the user input field of the prompt box, then you can leave out the second set of quotes in the prompt( ) instance.

(2) For returning the page address, it's a better idea to use a window.location or location.href command than to use a document.location command; as noted in Blog Entry #13, the location property of the document object is deprecated.

(3) Somewhat unintuitively, Joe variabilizes "My Great Page" by putting it in the <title></title> in the document head and then assigning document.title to a ttl variable. Hmmm...who would have thought of that? In my own answer to the assignment, which appears below, I for this part of the script simply wrote: var mgp = "My Great Page";

(4) With respect to the alert box message:
(a) In the assignment, "Hello", the first comma, and the concluding exclamation point become in the answer "Hi", a period, and a period, respectively. (Arrrgh!! I warned you that Joe can be sloppy...or is he deliberately trying to annoy the fastidious types in the audience?)
(b) In the answer, the order of the ttl and page variables in the instance of the alert( ) method is incorrect (the order is correct/reversed in the page's source).

Putting it all together, here is my answer:

<script type="text/javascript">
function greeting( ) {
fn = window.prompt("What is your first name?");
ln = window.prompt("What is your last name?");
pa = location.href;
mgp = "My Great Page!";
window.alert("Hello " + fn + " " + ln + ", Welcome to " + pa + ", " + mgp); }
greeting( );
</script>

The JavaScript Function Object

Finally, I would be remiss if I did not bring to your attention that JavaScript has a built-in Function object, with attendant properties and methods (none of which turn up in any of the HTML Goodies primers or script tips, BTW), for those programmers who might find a use for it.

HTML Goodies' JavaScript Primers #10, which we'll look over in the next post, heralds a return to the topic of event handlers, focusing specifically on the "act[ing] after the fact" onMouseOut and onUnload commands. See you then.

reptile7


Powered by Blogger

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