DHTML Lab - dhtmlab.com - Hierarchical Menus Ver. 3 - Addendum VI (v3.06) | 3 | WebReference

DHTML Lab - dhtmlab.com - Hierarchical Menus Ver. 3 - Addendum VI (v3.06) | 3

Logo

Hierarchical Menus Ver. 3 - Addendum VI (v3.06)
fixes and improvements for Navigator


The Font Family Problem

Recall that we chose the font family for our menu item text with the fntFam parameter variable declared in our HTML page. For example:

fntFam = "Arial";

In the itemSetup() function, the value of fntFam becomes the value of the FACE= attribute of the FONT tag which Navigator uses to style the item text:

htmStr = "<FONT FACE=" + fntFam + " POINT-SIZE=" + fntSiz + ">" + htmStr+ "</FONT>";

For the sake of our examples, let's assume the item text is My Item Text, and the point size, specified by fntSiz, is 10. If we specify Arial as the font family, then the generated HTML to be included in the item layer is:

<FONT FACE=Arial POINT-SIZE=10>My Item Text</FONT>

No problem. The text is rendered in Arial and the browser will substitute a similar font if Arial is not available on the user's system. This is the expected behavior.

Let's assume that we specify a simple two-item list for fntFam, like this:

fntFam = "Arial,Geneva";

The generated HTML will be:

<FONT FACE=Arial,Geneva POINT-SIZE=10>My Item Text</FONT>

Again, we will get the expected behavior. That is, if Arial is not available to the user, Geneva will be substituted. If Geneva is not available, the browser will chose a similar font from the user's installed fonts.

But, let's say the two-item list is declared with a space after the comma:

fntFam = "Arial, Geneva";

Our HTML will then be:

<FONT FACE=Arial, Geneva POINT-SIZE=10>My Item Text</FONT>

In this case, Geneva is not recognized as part of the list. If Arial is not available, the browser will not substitute Geneva. It will use its own judgement, as in the first example, above.

The problem originates, of course, with our failure to enclose the font list in quotes. The HTML specification requires that all tag attribute values be wrapped in quotes. It also states that all attribute values are interpreted as string values, even integers like the 10 above. Therefore, since all attribute values are string values, it has become a common bad habit to omit the quotes, as they are redundant if their only purpose is to identify strings. If the quotes are omitted, the browser needs an alternative method to determine the end of the string. It assumes the string has ended when it encounters a space. In the last example above, Geneva is interpreted as a new attribute, albeit one without a value, like GENEVA=, and since it doesn't support the GENEVA= attribute, it ignores it. In other words, the browser thinks the tag reads:

<FONT FACE="Arial," GENEVA= POINT-SIZE="10">My Item Text</FONT>

Simple Fix

The fix, is of course, elementary: We should generate valid HTML by including quotes. In our case, these are single quotes since we are building a string already enclosed in double quotes:

htmStr = "<FONT FACE='" + fntFam + "' POINT-SIZE='" + fntSiz + "'>" + htmStr+ "</FONT>";

The generated HTML will then be:

<FONT FACE='Arial, Geneva' POINT-SIZE='10'>My Item Text</FONT>

The browser now recognizes a string with two values separated by a comma. If Arial is not available, it will substitute Geneva before using any other font.

Preventive Medicine

There is another place in our script where this quote-omission can cause errors. When we define the image to be used when signifying the existence of child menus, we do not provide quotes for the SRC= attribute:
imgStr = "<IMG SRC="+ imgSrc +" WIDTH="+ imgSiz +" HEIGHT="+ imgSiz +" BORDER=0 VSPACE=2 "+ imgSuf;

If our image filename has a space in it, we would have the same problem as we did with the font family. For example:

imgSrc = "my triangle.gif";

The generated HTML would be:

<IMG SRC=my triangle.gif WIDTH=mywidth HEIGHT=myheight BORDER=0 VSPACE=2>

The browser would try to render it as:

<IMG SRC=my TRIANGLE.GIF= WIDTH=mywidth HEIGHT=myheight BORDER=0 VSPACE=2>

So, let's fix this mistake as well, by substituting this statement:

imgStr = "<IMG SRC='"+ imgSrc +"' WIDTH="+ imgSiz +" HEIGHT="+ imgSiz +" BORDER=0 VSPACE=2 "+ imgSuf;

When Two Set of Quotes are Not Enough

In version 3.05, we introduced a new minor feature: the display of menu item link URLs in the status bar. The Navigator version of our script creates links (<A>) in the item layer, so we included this statement, to display the URL when the user moused over the link:

eval("this.document.links[0].onmouseover = function(){menuLoc.status='"+ this.linkText +"';return true}");

Notice that we included the single quotes in the statement, to enclose the this.linkText value. However, in certain cases, the single quotes are not the proper choice. If you specify a JavaScript URL in the menu array, you may be already be using single quotes. For example:

"External Page","javascript:window.open('http://www.externalurl.com/')",0,

or

"Load in top","javascript:top.location='http://www.newurl.com/'",0,

This leads to single quotes nested within single quotes. This repitition is not allowed and the browser will not recognize the true form or length of the string. The proper method is to provide a set of double quotes to enclose the single quotes, by escaping them:

eval("this.document.links[0].onmouseover = function(){menuLoc.status=\""+ this.linkText +"\";return true}");

Got it? Now Forget It

The JavaScript URL-related problem has been described only to help those who encountered the problem understand its origin. This is not a fix that we will be implementing in version 3.06, because it relates to the item link tags, and we are going to do away with these tags forever!


Produced by Peter Belesis and

All Rights Reserved. Legal Notices.
Created: Mar 09, 1999
Revised: Mar 09, 1999

URL: http://www.webreference.com/dhtml/column21/addendum6/col21addVI2.html