reptile7's JavaScript blog
Thursday, November 22, 2007
Rolling Out the Yellow Carpet, Part 2
Blog Entry #95

Today's post updates the layer-based "drop down menu" script of HTML Goodies' JavaScript Script Tips #76-78; a cross-browser demo will follow.

From layer to div

We begin by converting the click layer to a div element. Replace the layer element start-tag with:

<div id="click">
<!-- And, of course, replace </layer> with </div>. -->

"Where are the showmenu( ) and unshow( ) function calls??" We'll get to them in the "Better function triggers" section below.

Here's the CSS we'll apply to the click div element:

#click {
background-color: yellow;
position: absolute;
left: 200px;
top: 25px;
clip: rect(0px, 250px, 25px, 0px); }

The CSS position, left, and top properties are detailed in Chapter 9 ("Visual formatting model") of the CSS 2.1 Specification. If you'd rather not slog through the W3C's material (can't say that I blame you), then check out HTML Goodies' "So, You Want Positioning, Huh?" tutorial for a kinder, gentler discussion of CSS absolute positioning.

The CSS clip property is detailed here in Chapter 11 ("Visual effects") of the CSS 2.1 Specification; it is largely analogous to the layer element's clip attribute but with an important exception: its four length values set, in order, the top, right, bottom, and left edges of the initially visible region of the click div element.

Regarding the rect part of the clip property value, the W3C notes, In CSS 2.1, all clipping regions are rectangular. We anticipate future extensions to permit non-rectangular clipping.

The link menu

We next turn to the link menu's table element container, whose start-tag is:

<table border="0" cellspacing="10">

If desired, the border and cellspacing attributes (neither of which is deprecated) can be replaced with the following style rule set:

table {
border: 0;
border-collapse: separate;
border-spacing: 10px; }

The CSS border-collapse and border-spacing properties are discussed here in Chapter 17 ("Tables") of the CSS 2.1 Specification.

Preceding the table is an "HTML Goodies Categories" string marked up with a font element:

<font face="arial black" color="black">HTML Goodies Categories</font>

The "HTML Goodies Categories" string is semantically a table caption, so let's mark it up instead with a caption element:

<caption>HTML Goodies Categories</caption>
<tr> <!-- etc. -->

The font element's face and color attributes can be replaced with the following style rule set:

caption {
font-family: "arial black"; /* typeface values containing whitespace should be quoted */
color: black; }

Philip Shaw's "code style" Web site shows here that Arial Black is a "most common" font on both PC and Mac computers; however, to not leave out any users that don't have it, you might want to replace the above font-family declaration with:

font-family: arial, sans-serif; font-weight: bold;

As a font element string, the "HTML Goodies Categories" is left-justified with respect to the parent layer element, but as a caption element string, it becomes centered with respect to the parent table element; you can add a text-align: left; declaration to the caption CSS if you'd like to keep it left-justified.

The links in the table cells are given a 'one smaller'* font size relative to the font size of the "HTML Goodies Categories" string via the font element and its size attribute, e.g.:

<td><font size="-1"><a href="">Script Tips</a></font></td>
<!-- *In practice on my computer, if the "HTML Goodies Categories" string has a 16pt font size, then the size="-1" markup gives the "Script Tips" string a 13pt font size. -->

The table cell font elements can be replaced collectively by one simple CSS rule:

a { font-size: smaller; }

We finally address the links themselves, all of which are defective in one way or another; in source order:

(1) The "Script Tips" link leads to a "404 - File not found" page; the actual Script Tips URL is

(2) The "New Page" link also leads to a "404 - File not found" page; it is meant to lead to the About HTML Goodies sector, whose actual URL is

(3) The "Beyond HTML" link is meant to lead to the index page of the Beyond HTML directory; the URL is correct but the page in question is not reliably accessible - upon multiple attempts to follow this link, I was often routed to the HTML Goodies home page.

(4) Bizarrely, the "Tutorials" link takes me to a "404 - File not found" page when using MSIE and to the Getting Started Tutorial sector when using Netscape! It is meant to lead to the index page of the HTML and Graphics Tutorials directory, whose actual URL is

(5) The "Newsletters" link leads to a "404 - File not found" page; the actual Newsletter Archive URL is

(6) The "Master List" link leads to a "404 - File not found" page; the actual Master List URL is

I don't particularly like this set of link targets and will use a different set for my demo below.

The script element

My first go at revamping the script element's showmenu( ) function

var startx = 25;
function showmenu( ) {
for (j = 0; j < 70; j++) {
document.getElementById("click").style.clip = "rect(0, 250, " + startx + ", 0)";
for (x = 0; x < #; x++) {
void(0); } } }

was semi-successful; the above code displayed the initially invisible region of the click div element but did so all at once and not gradually, regardless of the number (#) that I used for the inner for loop count, when using either MSIE 5.1.6 or Netscape 7.02. This outcome could have been expected, however; as documented in Blog Entry #45, neither of these browsers was able to cleanly separate the effects of the nested for loops of the animation script of HTML Goodies' JavaScript Primers #28.

Moreover, even if a user's browser executes the for loops per the script author's intention, the speed of the click rollout would be a function of the user's processor speed, which is obviously not desirable.

Fortunately and alternatively, a gradual, processor-independent click rollout is easily achieved by recursively calling the showmenu( ) function in a scheduled manner via the setTimeout( ) method of the window object:

var startx = 25;
function showmenu( ) {
document.getElementById("click").style.clip = "rect(0, 250, " + startx + ", 0)";
if (startx < 95) window.setTimeout("showmenu( );", 70); }

The above setTimeout( ) command produces a ≅5-second rollout (70 milliseconds/pixel × 70 pixels = 4900 milliseconds).

The corresponding unshow( ) function is:

function unshow( ) {
document.getElementById("click").style.clip = "rect(0, 250, " + startx + ", 0)";
if (startx > 25) window.setTimeout("unshow( );", 70); }

Better function triggers

For this entry, I originally intended to write a short section on the return false statements appearing in the click layer's onmouseover/onmouseout attribute values. Here's what Joe says about these statements at the end of Script Tip #76:
Note the returns are false. That means the function effect will not remain. It will want to go away, but we can't just have it popping in and out. We need to smooth that run.
If I understand him correctly, Joe is stating that the return false statements are needed to 'shut down' the showmenu( ) and unshow( ) functions when they are finished executing, and I thought, "This shouldn't be necessary.**" But for reasons beyond my understanding, the combination of the div element, the mouseevent function calls, and the gradual 'scrolling' does indeed on my computer result in some strange rollout/rollup behavior. I can initially roll out the link menu without any problems, but, for example, within the click yellow rectangle, as soon as I move the mouse cursor off of the "HTML Goodies Categories" string, the menu spontaneously rolls back up and then often rolls back down again, with or without the return false statements - not good if a user wanted to follow any of the links, needless to say. After much experimentation, I was able to "smooth" the situation somewhat via the use of the JavaScript event object plus some browser-specific coding that, as a matter of principle, I would just as soon not get into here.

I don't care for the mouseevent interface anyway, and it occurred to me that push buttons

<button type="button" onclick="showmenu( );">Roll It Out</button>
<button type="button" onclick="unshow( );">Roll It Up</button>

might be more reliable tools for calling the showmenu( ) and unshow( ) functions; this proved to be the case.

**More generally, the cancelation of events via a false function return can be used to suppress the default behaviors of certain HTML elements: for a good example thereof, see HTML Goodies' "Checkboxes: Only Two" tutorial, which we discussed in Blog Entry #47. But there's nothing to suppress - at least on the HTML side - when the mouse cursor is moved over and away from a layer or div element, so the return false statements should be deletable.


In the div below, click the Roll It Out button to roll out the link menu; each of the links is 'live' as of this writing, and will open in a new browser window. Clicking the Roll It Up button will roll up the link menu.

In Script Tips #76 and #78, Joe links to a tutorial that discusses a complementary MSIE-specific drop-down menu script, which we'll check over in the next post.


Comments: Post a Comment

<< Home

Powered by Blogger

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