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

DHTML Lab - dhtmlab.com - Hierarchical Menus Ver. 3 - Addendum III (v3.03) | 3


Hierarchical Menus Ver. 3 - Addendum III (v3.03)
menus for Communicator/Navigator 4.5

Purpose of Offending Line - Recap

Once we have established the required width for the new layer, and the containing element it is to be placed in, using the arguments passed to makeElement(), we actually create it using the offending line:

eval(whichEl + "= new Layer(elWidth,whichContainer)");

Recall that a new layer is created dynamically using this syntax:

elementReference = new Layer(width,parentLayer)

So, if we wanted to create a layer to be referred to as elMenu1, with a width of 200 pixels, placed within the window, we would use this line:

elMenu1 = new Layer(200,window)

In our menu script, we create many layers and we do not know ahead of time what the elementReference will be. We go through the arrays and create menus dynamically, incrementing a counter which is attached to the "elMenu" prefix. Our first menu is elMenu1, our second, elMenu2, and so on. Component items are created in a similar fashion. We therefore first create a string and pass that string as the first argument of makeElement(). This string (whichEl) is combined with the new Layer() constructor, again in a string version, to create a string representation of the JavaScript statement. Assuming that whichEl is "elMenu1", this string concanetation initially looks like this:

whichEl + "= new Layer(elWidth,whichContainer)"

This is equal to:

"elMenu1 = new Layer(elWidth,whichContainer)"

We now have a string representation of the JavaScript statement that will create the new layer. If we evaluate this string using the eval() function, we execute the statement that the string represents, creating the new layer:

eval(whichEl + "= new Layer(elWidth,whichContainer)");

Well, we should create a new layer. And we do, in all Navigator 4.x versions except for 4.5. For reasons unknown, it does not like this combination in the eval() function. And only here! Other similar combinations in other scripts work fine. This is definitely a bug, and the worse kind for developers. It is inconsistent. A whole series of specific precedents must be present to recreate the bug behavior. The line is clean and simple, but it halts script execution.

The Solution

It seems the simplest solution is to omit the new Layer() constructor from the string to be evaluated. That is, we create the layer directly and assign it to a temporary local variable, which we call tmpLyr. Then, we evaluate a simple assignment statement where tmpLyr is assigned to whichEl:

tmpLyr = new Layer(elWidth,whichContainer);
eval(whichEl + "= tmpLyr");

Still assuming that we are creating elMenu1, these statements are the same as:

tmpLyr = new Layer(elWidth,whichContainer);
elMenu1 = tmpLyr;

This two-step layer creation avoids the Navigator4.5 bug, and does not affect other Navigator versions, since it is simply a rearrangement of the statement.

The new makeElement():

The makeElement() function, in its version 3.03 incarnation, reads like this:

function makeElement(whichEl,whichWidth,whichParent,whichContainer) {
   if (NS4) {
      if (whichWidth) {
         elWidth = whichWidth;
      else {
         elWidth = (whichContainer) ? whichContainer.menuWidth : whichParent.menuWidth;
         if (whichContainer) elWidth = elWidth-(borWid*2)-(itemPad*2);
      if (!whichContainer) whichContainer = menuLoc;
         tmpLyr = new Layer(elWidth,whichContainer);
         eval(whichEl + "= tmpLyr");
   else {
      elStr = "<DIV ID=" + whichEl + " STYLE='position:absolute'></DIV>";
      if (isFrames) eval(whichEl + "= menuLoc." + whichEl);
   return eval(whichEl);

The solution may be elementary, but the bug was difficult to isolate.On the next page, we reproduce the complete hierMenus.js external file. Please upgrade to this new version.

Produced by Peter Belesis and

All Rights Reserved. Legal Notices.
Created: Dec 15, 1998
Revised: Dec 15, 1998

URL: http://www.webreference.com/dhtml/column21/addendum3/col21addIII3.html