Newsgroup: it.comp.lang.javascript
Titolo: Posizionare menu in una cella

Ciao a tutti ...
Ho creato un menu con il tool DHTML Menu Builder che in pratica crea il
classico drop down menu.
Quando inserisco il menu nella mia pagina html questo si posiziona in
alto a sx ... mentre io lo vorrei nella cella di una tabella.
Credo sia un problema generale visto che lo stesso mi capita con altri
menu trovati in rete.
Come posso ovviare a questo problema?
-- 
Posted via Mailgate.ORG Server - 
http://www.Mailgate.ORG

 Ho creato un menu con il tool DHTML Menu Builder che in pratica crea il
classico drop down menu.
Ti rispondo come ho risposto pochi giorni fa a un'altra persona che diceva
"sto usando il famosissimo menù di pincopallino"....
Non esistono "classici drop down menu", ogni menù si può fare in 100 modi
diversi => se stai usando un tool prefatto ti consiglio vivamente di
chiedere all'autore (a meno che qualcuno qui non lo abbia già usato, se sei
fortunello...)
-- 
"That until there is no longer first class
And second class citizens of any nation
Until the colour of a man's skin
Is of no more significance than the colour of his eyes
Me say war"
B.M. -- 

Si forse hai ragione ... io mi riferisco a questo script qui ...
<html>
<head>
<title>Popup Menu Demonstration</title>
<style type="text/css">
<!--
.lowText { text-decoration: none; color: #000000; font: 12px Arial,
Helvetica }
.highText { text-decoration: none; color: #FFFFFF; font: 12px Arial,
Helvetica }
.itemBorder { border: 1px solid #666666 }
.itemBorderBlank { border: 1px solid #CCCCDD }
.buttonText { text-decoration: none; color: #FFCC99; font: Bold 12px
Arial, Helvetica }
.buttonHover { text-decoration: none; color: #99CCFF; font: Bold 12px
Arial, Helvetica; padding: 1px }
.buttonBorder { border: 1px outset #339966 }
.buttonBorderOver { border: 1px inset #CC9966 }
-->
</style>
</head>
<!-- The margins aren't really necessary here, it's just for this
example layout. -->
<body marginwidth="100" marginheight="40" style="margin: 0"
bgcolor="#FFFFFF">
<!-- You might want to position the menu over a background, like a
table/image -->
<table bgcolor="#336699" width="100%" border="1" cellpadding="0"
cellspacing="0">
<tr><td height="17" align="center"><font size="1"
color="#336699">.&nbsp;</font></td></tr></table>
<script language="JavaScript1.2"><!--
var isDOM=document.getElementById?1:0;
var isIE=document.all?1:0;
var isNS4=navigator.appName=='Netscape'&&!isDOM?1:0;
var isIE4=isIE&&!isDOM?1:0;
var isOp=window.opera?1:0;
var isDyn=isDOM||isIE||isNS4;
function getRef(id, par)
{
 par=!par?document:(par.navigator?par.document:par);
 return (isIE ? par.all[id] :
  (isDOM ? (par.getElementById?par:par.ownerDocument).getElementById(id)
:
  (isNS4 ? par.layers[id] : null)));
}
function getSty(id, par)
{
 var r=getRef(id, par);
 return r?(isNS4?r:r.style):null;
}
if (!window.LayerObj) var LayerObj = new Function('id', 'par',
 'this.ref=getRef(id, par); this.sty=getSty(id, par); return this');
function getLyr(id, par) { return new LayerObj(id, par) }
function LyrFn(fn, fc)
{
 LayerObj.prototype[fn] = new Function('var
a=arguments,p=a[0],px=isNS4||isOp?0:"px"; ' +
  'with (this) { '+fc+' }');
}
LyrFn('x','if (!isNaN(p)) sty.left=p+px; else return
parseInt(sty.left)');
LyrFn('y','if (!isNaN(p)) sty.top=p+px; else return parseInt(sty.top)');
LyrFn('vis','sty.visibility=p');
LyrFn('bgColor','if (isNS4) sty.bgColor=p?p:null; ' +
 'else sty.background=p?p:"transparent"');
LyrFn('bgImage','if (isNS4) sty.background.src=p?p:null; ' +
 'else sty.background=p?"url("+p+")":"transparent"');
LyrFn('clip','if (isNS4)
with(sty.clip){left=a[0];top=a[1];right=a[2];bottom=a[3]} ' +
 'else sty.clip="rect("+a[1]+"px "+a[2]+"px "+a[3]+"px "+a[0]+"px)" ');
LyrFn('write','if (isNS4) with (ref.document){write(p);close()} else
ref.innerHTML=p');
LyrFn('alpha','var f=ref.filters,d=(p==null); if (f) {' +
 'if (!d&&sty.filter.indexOf("alpha")==-1) sty.filter+="
alpha(opacity="+p+")"; ' +
 'else if (f.length&&f.alpha)
with(f.alpha){if(d)enabled=false;else{opacity=p;enabled=true}} }' +
 'else if (isDOM) sty.MozOpacity=d?"":p+"%"');
function setLyr(lVis, docW, par)
{
 if (!setLyr.seq) setLyr.seq=0;
 if (!docW) docW=0;
 var obj = (!par ? (isNS4 ? window : document.body) :
  (!isNS4 && par.navigator ? par.document.body : par));
 var IA='insertAdjacentHTML', AC='appendChild',
newID='_js_layer_'+setLyr.seq++;
 if (obj[IA]) obj[IA]('beforeEnd', '<div id="'+newID+'"
style="position:absolute"></div>');
 else if (obj[AC])
 {
  var newL=document.createElement('div');
  obj[AC](newL); newL.id=newID; newL.style.position='absolute';
 }
 else if (isNS4)
 {
  var newL=new Layer(docW, obj);
  newID=newL.id;
 }
 var lObj=getLyr(newID, par);
 with (lObj) if (ref) { vis(lVis); x(0); y(0);
sty.width=docW+(isNS4?0:'px') }
 return lObj;
}
var CSSmode=document.compatMode;
CSSmode=(CSSmode&&CSSmode.indexOf('CSS')!=-1)||isDOM&&!isIE||isOp?1:0;
if (!
window.page
) var page = { win: window, minW: 0, minH: 0, MS:
isIE&&!isOp,
 db: CSSmode?'documentElement':'body' }
page.winW=function()
 { with (this) return Math.max(minW,
MS?win.document[db].clientWidth:win.innerWidth) }
page.winH=function()
 { with (this) return Math.max(minH,
MS?win.document[db].clientHeight:win.innerHeight) }
page.scrollX=function()
 { with (this) return MS?win.document[db].scrollLeft:win.pageXOffset }
page.scrollY=function()
 { with (this) return MS?win.document[db].scrollTop:win.pageYOffset }
function popOver(mN, iN) { with (this)
{
 // Cancel any pending menu hides from a previous mouseout.
 clearTimeout(hideTimer);
 // Set the 'over' variables to point to this item.
 overM = mN;
 overI = iN;
 // Call the 'onMouseOver' event if it exists, and the item number is 1
or more.
 if (iN && this.onmouseover) onmouseover(mN, iN);
 // Remember what was lit last time, and compute a new hierarchy.
 litOld = litNow;
 litNow = new Array();
 var litM = mN, litI = iN;
 while(1)
 {
  litNow[litM] = litI;
  // If we've reached the top of the hierarchy, exit loop.
  if (litM == 'root') break;
  // Otherwise repeat with this menu's parent.
  litI = menu[litM][0].parentItem;
  litM = menu[litM][0].parentMenu;
 }
 // If the two arrays are the same, return... no use hiding/lighting
otherwise.
 var same = true;
 for (var z in menu) if (litNow[z] != litOld[z]) same = false;
 if (same) return;
 // If this is a different menu, clear another pending show.
 clearTimeout(showTimer);
 // Cycle through menu array, lighting and hiding menus as necessary.
 for (thisM in menu) with (menu[thisM][0])
 {
  // Doesn't exist yet? Keep rollin'...
  if (!lyr) continue;
  // The number of this menu's item that is to be lit, undefined if
none.
  litI = litNow[thisM];
  oldI = litOld[thisM];
  // If it's lit now and wasn't before, highlight...
  if (litI && (litI != oldI)) changeCol(thisM, litI, true);
  // If another item was lit but isn't now, dim the old item.
  if (oldI && (oldI != litI)) changeCol(thisM, oldI, false);
  // Make sure if it's lit, it's shown, and set the visNow flag.
  if (litI && !visNow && (thisM != 'root'))
  {
   showMenu(thisM);
   visNow = true;
  }
  // If this menu has no items from the current hierarchy in it, and is
currently
  // onscreen, call the hide function.
  if (isNaN(litI) && visNow)
  {
   hideMenu(thisM);
   visNow = false;
  }
 }
 // Get target menu to show - if we've got one, position & show it.
 // If this menu is set to show submenus on click, skip this.
 nextMenu = '';
 if ((menu[mN][iN].type == 'sm:') && !menu[mN][0].subsOnClick)
 {
  // The target menu and the layer object of the current menu itself
(not this item).
  var targ = menu[mN][iN].href, lyrM = menu[mN][0].lyr;
// EXTRA CODE - Uncomment these lines to enable dynamic create-as-needed
menu support,
// where you can create only the root menu on page load and others when
you point at them.
// I would recommend using this for single-frame menus only, and
changing the "Events"
// section of the code to call pMenu.update(false, 'root') on page load
for all browsers
// and disabling "fast" inline creation mode. Bear in mind this won't
work in Opera 5/6.
//if (!menu[targ][0].lyr) update(false, targ);
//if (!menu[targ][0].lyr) return;
  // Either show immediately or after a delay if set by passing it to
the position and show functions.
  // Set nextMenu to the impending show, so the popOut() function knows
when not to cancel it.
  var showStr = 'with ('+myName+') { menu.'+targ+'[0].visNow = true; ' +
   'position("'+targ+'"); showMenu("'+targ+'") }';
  nextMenu = targ;
  if (showDelay) showTimer = setTimeout(showStr, showDelay);
  else eval(showStr);
 }
}}
function popOut(mN, iN) { with (this)
{
 // Sometimes, across frames, overs and outs can get confused.
 // So, return if we're exiting an item we have yet to enter...
 if ((mN != overM) || (iN != overI)) return;
 // Evaluate the onmouseout event, if any.
 if (this.onmouseout) onmouseout(mN, iN);
 var thisI = menu[mN][iN];
 // Stop showing another menu if this item isn't pointing to the same
one.
 if (thisI.href != nextMenu)
 {
  clearTimeout(showTimer);
  nextMenu = '';
 }
 // Hide all menus rapidly (if it's a root menu item without a popout)
or as specified.
 // Remember that the timeout is cancelled by another instance of the
over function.
 // Calling 'over("root", 0)' hides all menus but the root menu, and
highlights no items.
 // If hideDelay equals zero the menus are never hidden.
 if (hideDelay)
 {
  var delay = ((mN == 'root') && (thisI.type != 'sm:')) ? 50 :
hideDelay;
  hideTimer = setTimeout(myName + '.over("root", 0)', delay);
 }
 // Clear the 'over' variables.
 overM = 'root';
 overI = 0;
}}
function popClick(mN, iN) { with (this)
{
 // Evaluate the onclick event, if any.
 if (this.onclick) onclick(mN, iN);
 var thisI = menu[mN][iN], hideM = true;
 with (thisI) switch (type)
 {
  // Targeting another popout? Either activate show-on-click or skip to
the end.
  case 'sm:':
  {
   if (menu[overM][0].subsOnClick)
   {
    menu[href][0].visNow = true;
    position(href);
    showMenu(href);
    hideM = false;
   }
   break;
  }
  // A JavaScript function? Eval() it and break out of switch.
  case 'js:': { eval(href); break }
  // Otherwise, point to the window if nothing else and navigate.
  case '': type = 'window';
  default: if (href) eval(type + '.location.href = "' + href + '"');
 }
 // Hide all menus if we're supposed to.
 if (hideM) over('root', 0);
}}
function popChangeCol(mN, iN, isOver) { with (this.menu[mN][iN])
{
 if (!lyr || !lyr.ref) return;
 // Pick a new background colour, and decide on whether it's an image
(contains a period?).
 var col = isOver?overCol:outCol;
 var bgFn = (col.indexOf('.')==-1) ? 'bgColor' : 'bgImage';
 // Then we do it before or after the text/border change due to Netscape
bugs.
 if (isNS4) lyr[bgFn](col);
 // Test for CSS text/border style changes, we can skip them if not
needed.
 // In Netscape 4, rewrite layer contents if required (causes a little
flickering)...
 // Otherwise manipulate the DOM tree for IE/NS6+ (faster than rewriting
contents).
 if ((overClass != outClass) || (outBorder != overBorder)) with (lyr)
 {
  if (isNS4) write(this.getHTML(mN, iN, isOver));
  else
  {
   ref.className = (isOver ? overBorder : outBorder);
   var chl = (isDOM ? ref.childNodes : ref.children)
   if (chl) for (var i = 0; i < chl.length; i++) chl[i].className =
isOver?overClass:outClass;
  }
 }
 if (!isNS4) lyr[bgFn](col);
 // Alpha filtering activated? Might as well set that then too...
 // Weirdly it has to be done after the border change, another random
Mozilla bug...
 if (outAlpha != overAlpha) lyr.alpha(isOver ? overAlpha : outAlpha);
}}
function popPosition(posMN) { with (this)
{
 // Pass a menu name to position, or nothing to position all menus.
 for (mN in menu)
 {
  if (posMN && (posMN != mN)) continue;
  with (menu[mN][0])
  {
   // If the menu hasn't been created or is not set to be visible, loop.
   if (!lyr || !lyr.ref || !visNow) continue;
   // Set up some variables and the initial calculated positions.
   var pM, pI, newX = eval(offX), newY = eval(offY);
   // Find its parent menu references, if it's not the topmost root
menu.
   if (mN != 'root')
   {
    pM = menu[parentMenu];
    pI = pM[parentItem].lyr;
    // Having no parent item is a bad thing, especially in cross-frame
code.
    if (!pI) continue;
   }
   // Find parent window for correct page object, or this window if not.
   var eP = eval(par);
   var pW = (eP && eP.navigator ? eP : window);
   // Find proper numerical values for the current window position +
edges, so menus
   // don't make a beeline for the upper-left corner of the page.
   with (pW.page) var sX=scrollX(), wX=sX+winW(), sY=scrollY(),
wY=winH()+sY;
   wX = isNaN(wX)||!wX ? 9999 : wX;
   wY = isNaN(wY)||!wY ? 9999 : wY;
   // Relatively positioned submenus? Add parent menu/item position &
check screen edges.
   if (pM && typeof(offX)=='number') newX = Math.max(sX,
    Math.min(newX+pM[0].lyr.x()+pI.x(), wX-menuW-(isIE?5:20)));
   if (pM && typeof(offY)=='number') newY = Math.max(sY,
    Math.min(newY+pM[0].lyr.y()+pI.y(), wY-menuH-(isIE?5:20)));
   // Assign the final calculated positions.
   lyr.x(newX);
   lyr.y(newY);
  }
 }
}}
function addProps(obj, data, names, addNull)
{
 for (var i = 0; i < names.length; i++) if(i < data.length || addNull)
obj[names[i]] = data[i];
}
function ItemStyle()
{
 // Like the other constructors, this passes a list of property names
that correspond to the list
 // of arguments.
 var names = ['len', 'spacing', 'popInd', 'popPos', 'pad', 'outCol',
'overCol', 'outClass',
  'overClass', 'outBorder', 'overBorder', 'outAlpha', 'overAlpha',
'normCursor', 'nullCursor'];
 addProps(this, arguments, names, true);
}
function popStartMenu(mName) { with (this)
{
 // Create a new array within the menu object if none exists already,
and a new menu object within.
 if (!menu[mName]) { menu[mName] = new Array(); menu[mName][0] = new
Object(); }
 // Clean out existing items in this menu in case of a menu update.
 // actMenu is a reference to this menu for addItem() function later,
while the local variable
 // aM is a quick reference to the current menu descriptor -- array
index 0, 1+ are items.
 actMenu = menu[mName];
 aM = actMenu[0];
 actMenu.length = 1;
 // Not all of these are actually passed to the constructor -- the last
few are null.
 // N.B: I pass 'isVert' twice so the first parameter (the menu name) is
overwritten & ignored.
 var names = ['isVert', 'isVert', 'offX','offY', 'width', 'itemSty',
'par',
  'parentMenu', 'parentItem', 'visNow', 'oncreate', 'subsOnClick'];
 addProps(aM, arguments, names, true);
 // extraHTML is a string added to menu layers for things like
dropshadows, backgrounds etc.
 aM.extraHTML = '';
 // Set the menu dimensions to zero initially. Also these are used to
position items.
 aM.menuW = aM.menuH = 0;
 // Reuse old layers if we can, no use creating new ones every time the
menus refresh.
 if (!aM.lyr) aM.lyr = null;
 
 // Assign a default oncreate event to the root menu to show it.
 if (mName == 'root') menu.root[0].oncreate = new
Function('this.visNow=true; ' +
  myName + '.position("root"); this.lyr.vis("visible")');
}}
function popAddItem() { with (this) with (actMenu[0])
{
 // 'with' the current menu object and active menu descriptor object
from startMenu().
 // Add these properties onto a new 'active Item' at the end of the
active menu.
 var aI = actMenu[actMenu.length] = new Object();
 // Add function parameters to object. Again, the last few are
undefined, set later.
 var names = ['text', 'href', 'type', 'itemSty', 'len', 'spacing',
'popInd', 'popPos',
  'pad', 'outCol', 'overCol', 'outClass', 'overClass', 'outBorder',
'overBorder',
  'outAlpha', 'overAlpha', 'normCursor', 'nullCursor',
  'iX', 'iY', 'iW', 'iH', 'lyr'];
 addProps(aI, arguments, names, true);
 // Find an applicable itemSty -- either passed to this item or the
menu[0] object.
 var iSty = (arguments[3] ? arguments[3] : actMenu[0].itemSty);
 // Loop through its properties, add them if they don't already exist
(overridden e.g. length).
 for (prop in iSty) if (aI[prop]+'' == 'undefined') aI[prop] =
iSty[prop];
 // In NS4, since borders are assigned to the contents rather than the
layer, increase padding.
 if (aI.outBorder)
 {
  if (isNS4) aI.pad++;
 }
 // The actual dimensions of the items, store here as properties so they
can be accessed later.
 aI.iW = (isVert ? width : aI.len);
 aI.iH = (isVert ? aI.len : width);
 // The spacing of the previous menu item in this menu, if relevant.
 var lastGap = (actMenu.length > 2) ? actMenu[actMenu.length -
2].spacing : 0;
 // 'spc' is the amount we subtract from this item's position so borders
overlap a little.
 // Of course we don't do it to the first item.
 var spc = ((actMenu.length > 2) && aI.outBorder ? 1 : 0);
 // We position this item at the end of the current menu's dimensions,
 // and then increase the menu dimensions by the size of this item.
 if (isVert)
 {
  menuH += lastGap - spc;
  aI.iX = 0; aI.iY = menuH;
  menuW = width; menuH += aI.iH;
 }
 else
 {
  menuW += lastGap - spc;
  aI.iX = menuW; aI.iY = 0;
  menuW += aI.iW; menuH = width;
 }
 // When we are running in proper 'CSS1Compat' mode, borders affect
widths differently, so we
 // subtract some pixels here to go with the old 'loose' specification.
Swap this around if you
 // want your documents to conform with the new specs.
 if (aI.outBorder && CSSmode)
 {
  aI.iW -= 2;
  aI.iH -= 2;
 }
}}
function popGetHTML(mN, iN, isOver) { with (this)
{
 var itemStr = '';
 with (menu[mN][iN])
 {
  var textClass = (isOver ? overClass : outClass);
  // If we're supposed to add a popout indicator, add it before text so
it appears below in NS4.
  if ((type == 'sm:') && popInd)
  {
   if (isNS4) itemStr += '<layer class="' + textClass + '" left="'+
((popPos+iW)%iW) +
    '" top="' + pad + '" height="' + (iH-2*pad) + '">' + popInd +
'</layer>';
   else itemStr += '<div class="' + textClass + '" style="position:
absolute; left: ' +
    ((popPos+iW)%iW) + 'px; top: ' + pad + 'px; height: ' + (iH-2*pad) +
'px">' + popInd + '</div>';
  }
  // For NS4, if a border is assigned, add a spacer to push border out
to layer edges.
  // Add a link both to generate an onClick event and to stop the ugly
I-beam text cursor appearing.
  if (isNS4) itemStr += (outBorder ? '<span class="' +
(isOver?overBorder:outBorder) +
   '"><spacer type="block" width="' + (iW-8) + '" height="' + (iH-8) +
'"></span>' : '') +
   '<layer left="' + pad + '" top="' + pad + '" width="' + (iW-2*pad) +
'" height="' +
   (iH-2*pad) + '"><a class="' + textClass + '" href="#" ' +
   'onClick="return false" onMouseOver="status=\'\'; ' + myName +
'.over(\'' + mN + '\',' +
   iN + '); return true">' + text + '</a></layer>';
  // IE4+/NS6 is an awful lot easier to work with sometimes.
  else itemStr += '<div class="' + textClass + '" style="position:
absolute; left: ' + pad +
   'px; top: ' + pad + 'px; width: ' + (iW-2*pad) + 'px; height: ' +
(iH-2*pad) + 'px">' +
   text + '</div>';
 }
 return itemStr;
}}
// The main menu creation/update routine. The first parameter is 'true'
if you want the script
// to use document.write() to create the menus. Second parameter is
optionally the name of one
// menu only to update rather then create all menus.
function popUpdate(docWrite, upMN) { with (this)
{
 // 'isDyn' (set at the very top of the script) signifies a
DHTML-capable browser.
 if (!isDyn) return;
 // Loop through menus, using properties of menu description object
(array index 0)...
 for (mN in menu) with (menu[mN][0])
 {
  // If we're updating one specific menu, only run the code for that.
  if (upMN && (upMN != mN)) continue;
  // Variable for holding HTML for items.
  var str = '';
  // Remember, items start from 1 in the array (0 is menu object itself,
above).
  // Also use properties of each item nested in the other with() for
construction.
  for (var iN = 1; iN < menu[mN].length; iN++) with (menu[mN][iN])
  {
   // An ID for divs/layers contained within the menu.
   var itemID = myName + '_' + mN + '_' + iN;
   // Now is a good time to assign another menu's parent to this if
we've got a popout item.
   var targM = menu[href];
   if (targM && (type == 'sm:'))
   {
    targM[0].parentMenu = mN;
    targM[0].parentItem = iN;
   }
   // Have we been given a background image? It'll have a period in its
name if so...
   var isImg = (outCol.indexOf('.') != -1) ? true : false;
   // NS6 uses a different cursor name for the 'hand' cursor than IE.
   if (!isIE && normCursor=='hand') normCursor = 'pointer';
   // Create a div or layer text string with appropriate
styles/properties.
   // OK, OK, I know this is a little obtuse in syntax, but it's
small...
   // At the end we set the alpha transparency (if specified) and the
mouse cursor.
   if (isDOM || isIE4)
   {
    str += '<div id="' + itemID + '" ' + (outBorder ?
'class="'+outBorder+'" ' : '') +
     'style="position: absolute; left: ' + iX + 'px; top: ' + iY + 'px;
width: ' + iW +
     'px; height: ' + iH + 'px; z-index: 1000; background: ' +
(isImg?'url('+outCol+')':outCol) +
     ((typeof(outAlpha)=='number') ? '; filter: alpha(opacity='+
outAlpha + '); -moz-opacity: ' +
      (outAlpha/100) : '') +
     '; cursor: ' + ((type!='sm:' && href) ? normCursor : nullCursor) +
'" ';
   }
   else if (isNS4)
   {
    // NS4's borders must be assigned within the layer so they stay when
content is replaced.
    str += '<layer id="' + itemID + '" left="' + iX + '" top="' + iY +
'" width="' +
     iW + '" height="' + iH + '" z-index="1000" ' +
     (outCol ? (isImg ? 'background="' : 'bgcolor="') + outCol + '" ' :
'');
   }
   // Add mouseover and click handlers, contents, and finish div/layer.
   var evtMN = '(\'' + mN + '\',' + iN + ')"';
   str += 'onMouseOver="' + myName + '.over' + evtMN +
     ' onMouseOut="' + myName + '.out' + evtMN +
     ' onClick="' + myName + '.click' + evtMN + '>' +
     getHTML(mN, iN, false) + (isNS4 ? '</layer>' : '</div>');
  // End loop through items and with(menu[mN][iN]).
  }
  // The parent frame for this menu, if any.
  var eP = eval(par);
  // Do not ask me why Opera makes me set a timeout now rather than
later, or in fact have
  // to set a timeout at all to get references to the divs we are about
to create.
  // But, it makes the cross-frame version of the script actually work,
so there's a benefit.
  setTimeout(myName + '.setupRef(' + docWrite + ', "' + mN + '")', 50);
  // Initial menu visibility, hidden unless tweaked otherwise.
  var mVis = visNow ? 'visible' : 'hidden';
  // For Fast creation mode (default for IE, NS6, Opera), write the
menus to the document now.
  // I'm adding a bit to the widths for safety as borders are different
across browsers.
  if (docWrite)
  {
   // Find the right target frame.
   var targFr = (eP && eP.navigator ? eP : window);
   targFr.document.write('<div id="' + myName + '_' + mN + '_Div"
style="position: absolute; ' +
    'visibility: ' + mVis + '; left: 0px; top: 0px; width: ' + (menuW+2)
+ 'px; height: ' +
    (menuH+2) + 'px; z-index: 1000">' + str + extraHTML + '</div>');
  }
  else
  {
   // Create a new layer/div object dynamically using my setLyr()
function above.
   // If we've got a layer created already, there's no use creating
another!.
   // In IE4, we must shrink the menus to stop them sizing to the full
body size -- thanks
   // to Jeff Blum and Paul Maden for debugging this for me :). If the
layer has been created,
   // we've got to set a timeout to fix up IE4 again for some obscure
reason.
   if (!lyr || !lyr.ref) lyr = setLyr(mVis, menuW, eP);
   else if (isIE4) setTimeout(myName + '.menu.' + mN +
'[0].lyr.sty.width=' + (menuW+2), 50);
   // Give it a high Z-index, and write its content.
   with (lyr) { sty.zIndex = 1000; write(str + extraHTML) }
  }
 // End loop through menus and with (menu[mN][0]).
 }
}}
function popSetupRef(docWrite, mN) { with (this) with (menu[mN][0])
{
 // Get a reference to a div, only needed for Fast creation mode.
 if (docWrite || !lyr || !lyr.ref) lyr = getLyr(myName + '_' + mN +
'_Div', eval(par));
 // Loop through menu items again to set up individual references.
 for (var i = 1; i < menu[mN].length; i++)
  menu[mN][i].lyr = getLyr(myName + '_' + mN + '_' + i,
(isNS4?lyr.ref:eval(par)));
 // Call the 'oncreate' method of this menu if it exists (e.g. to show
root menu).
 if (menu[mN][0].oncreate) oncreate();
}}
// *** POPUP MENU MAIN OBJECT CONSTRUCTOR ***
function PopupMenu(myName)
{
 // These are the properties of any PopupMenu objects you create.
 this.myName = myName;
 // Manage what gets lit and shown when.
 this.showTimer = 0;
 this.hideTimer = 0;
 this.showDelay = 0;
 this.hideDelay = 500;
 this.showMenu = '';
 // 'menu': the main data store, contains subarrays for each menu e.g.
pMenu.menu['root'][];
 this.menu =  new Array();
 // litNow and litOld arrays control what items get lit in the
hierarchy.
 this.litNow = new Array();
 this.litOld = new Array();
 // The item the mouse is currently over. Used by click processor to
help NS4.
 this.overM = 'root';
 this.overI = 0;
 // The active menu, to which addItem() will assign its results.
 this.actMenu = null;
 // Functions to create and manage the menu.
 this.over = popOver;
 this.out = popOut;
 this.changeCol = popChangeCol;
 this.position = popPosition;
 this.click = popClick;
 this.startMenu = popStartMenu;
 this.addItem = popAddItem;
 this.getHTML = popGetHTML;
 this.update = popUpdate;
 this.setupRef = popSetupRef;
 // Default show and hide functions, overridden in the example script by
the clipping routine.
 this.showMenu = new Function('mName',
'this.menu[mName][0].lyr.vis("visible")');
 this.hideMenu = new Function('mName',
'this.menu[mName][0].lyr.vis("hidden")');
}
var hBar = new ItemStyle(40, 10, '', 0, 0, '#336699', '#6699CC',
'highText', 'highText', '', '',
 null, null, 'hand', 'default');
var subM = new ItemStyle(22, 0, '&gt;', -15, 3, '#CCCCDD', '#6699CC',
'lowText', 'highText',
 'itemBorder', 'itemBorder', null, null, 'hand', 'default');
var subBlank = new ItemStyle(22, 1, '&gt;', -15, 3, '#CCCCDD',
'#6699CC', 'lowText', 'highText',
 'itemBorderBlank', 'itemBorder', null, null, 'hand', 'default');
var button = new ItemStyle(22, 1, '&gt;', -15, 2, '#006633', '#CC6600',
'buttonText', 'buttonHover',
 'buttonBorder', 'buttonBorderOver', 80, 95, 'crosshair', 'default');
// A PopupMenu() object must be passed its own name so it can reference
itself when the menu
// is active. We also use a 'with' block to work with its properties and
functions below.
var pMenu = new PopupMenu('pMenu');
with (pMenu)
{
/
startMenu('root', false, 10, 0, 17, hBar);
// The text is a space then 'File', and this item pops out the 'mFile'
submenu when moused over
// as we've set 'sm:' as the action type. If you want to assign a click
action (e.g. navigating to
// a file) to one of these 'sm:' items, see the 'Optional Code' section
below.
addItem('&nbsp; File', 'mFile', 'sm:');
addItem('&nbsp; Edit', 'mEdit', 'sm:');
addItem('&nbsp; Help', 'mHelp', 'sm:');
// Next is an example of a Javascript function embedded in the menu, to
open a new window...
// Also, note the extra optional 4th and 5th parameters -- this menu
item is 80px long,
// rather than the default length from the ItemStyle.
addItem('&nbsp; Visit My Site',
'window.open("
http://www.twinhelix.com
")', 'js:', hBar, 80);
// This is a vertical menu positioned 0px across and 22px down from its
trigger, and is 80px wide.
startMenu('mFile', true, 0, 22, 80, subM);
// The URLs are set to # here, be sure to replace them with your
path/file names or JS functions!
// Also note how all the types are '', indicating these links open in
the current frame.
addItem('Open', '#', '');
addItem('Save', '#', '');
addItem('Reopen', 'mReopen', 'sm:');
addItem('Check for<br />Update...', '
http://www.twinhelix.com
', '',
subM, 38);
startMenu('mEdit', true, 0, 22, 80, subM);
addItem('Cut', '#', '');
addItem('Copy', '#', '');
addItem('Paste', '#', '');
addItem('Convert', 'mConvert', 'sm:');
// Popout slightly left of its trigger, for fun...
startMenu('mHelp', true, -10, 22, 80, subM);
// Instead of using spaces to indent, consider 'text-indent' in the
stylesheet class perhaps?
addItem('&nbsp; &nbsp; Contents', '#', '');
addItem('&nbsp; &nbsp; Search', '#', '');
// Here's an example of adding extra optional parameters to the
addItem() command.
// This item uses the subM ItemSyle (regardless of what the rest of this
menu uses), is 22px long,
// has 0px spacing after it, and a lesser-than-sign popout indicator
positioned 3px from the left
// edge of this item. Note that the parameters after the ItemStyle name
are in the same order as
// the ItemStyle command itself, and you can have as many as you want
(e.g. background colours).
addItem('&nbsp; &nbsp; About', 'mAbout', 'sm:', subM, 22, 0, '&lt;', 3);
// This is across but not down... a horizontal popout.
startMenu('mReopen', true, 85, 0, 120, button);
// Again these items have their own ItemStyles, and unique lengths /
spacings specified.
addItem('Recent Doc 1:<br />Schedule', '#', '', button, 35);
addItem('Recent Doc 2:<br />Cunning Plan', '#', '', button, 35, 5);
// Back to the normal submenu ItemStyle for this next item.
addItem('Etc. etc...', '#', '', subM);
// This uses the subBlank ItemStyle which gives the items no borders
when dim. The border around
// the whole menu comes from a JavaScript function in the "Menu Effects"
section.
startMenu('mConvert', true, 85, 0, 80, subBlank);
addItem('Windows', '#', '');
addItem('Unix', '#', '');
addItem('Macintosh', '#', '');
// Leftwards popout with a negative x and y relative to its trigger.
Custom height too.
startMenu('mAbout', true, -85, -18, 80, subM);
addItem('Leftwards!<br>And up!', '#', '', subM, 40);
}
addMenuBorder(pMenu, window.subBlank,
 null, '#666666', 1, '#CCCCDD', 2);
addDropShadow(pMenu, window.subM,
 [40,"#333333",6,6,-4,-4], [40,"#666666",4,4,0,0]);
addDropShadow(pMenu, window.subBlank,
 [40,"#333333",6,6,-4,-4], [40,"#666666",4,4,0,0]);
if (!isOp && navigator.userAgent.indexOf('rv:0.')==-1)
{
 pMenu.showMenu = new Function('mN','menuAnim(this, mN, 10)');
 pMenu.hideMenu = new Function('mN','menuAnim(this, mN, -10)');
}
if (!isNS4)
{
 // Write menus now in non-NS4 browsers, by calling the "Fast" mode
.update(true) method.
 pMenu.update(true);
 //anotherMenu.update(true);
}
else
{
 // For Netscape 4, back up the old onload function and make a new one
to update our menus.
 // This is the regular "Dynamic" mode menu update, it works in IE and
NS6 too if required.
 var popOldOL = window.onload;
 window.onload = function()
 {
  if (popOldOL) popOldOL();
  pMenu.update();
  //anotherMenu.update();
 }
}
// Other events must be assigned, these are less complicated, just add
or remove menu objects.
var nsWinW = window.innerWidth, nsWinH = window.innerHeight, popOldOR =
window.onresize;
window.onresize = function()
{
 if (popOldOR) popOldOR();
 if (isNS4 && (nsWinW!=innerWidth || nsWinH!=innerHeight))
history.go(0);
 pMenu.position();
 //anotherMenu.position();
}
window.onscroll = function()
{
 pMenu.position();
 //anotherMenu.position();
}
// NS4 can't reliably capture clicks on layers, so here's a workaround.
if (isNS4)
{
 document.captureEvents(Event.CLICK);
 document.onclick = function(evt)
 {
  with (pMenu) if (overI) click(overM, overI);
  //with (anotherMenu) if (overI) click(overM, overI);
  return document.routeEvent(evt);
 }
}
// Activate the window.onscroll() event in non-Microsoft browsers.
if (!isIE || isOp)
{
 var nsPX=pageXOffset, nsPY=pageYOffset;
 setInterval('if (nsPX!=pageXOffset || nsPY!=pageYOffset) ' +
 '{ nsPX=pageXOffset; nsPY=pageYOffset; window.onscroll() }', 50);
}
/*
pMenu.onclick = function(mN, iN) { with (this)
{
 // Do actions depending on the item that the mouse was over at the time
of the click.
 // You may with to use nested IFs or 'switch' statements etc. if you're
familiar with JS.
 if (mN == 'root')
 {
  if (iN == 1) status = 'Congratulations, you\'ve mastered clicking!';
  // Click on second item in root menu will navigate to 'edit.html'.
Copy and paste this for
  // each menu item to add click actions to 'sm:' items...
  if (iN == 2) location.href = 'edit.html';
  if (iN == 3) location.href = 'help.html';
 }
}}
// Set the status message to the URL if the 'action type' is nothing,
and clear on mouseout.
pMenu.onmouseover = function(mN, iN) { with (this)
{
 // By now, you either have my JS Object Browser script from my site or
you need it... try
 // embedding in an IFrame and typing 'pMenu' into its Go To field to
see the menu internals.
 with (menu[mN][iN]) if (!type) status = href;
}}
pMenu.onmouseout = function() { status = '' }
*/
function menuAnim(menuObj, menuName, dir)
{
 // The array index of the named menu (e.g. 'mFile') in the menu object
(e.g. 'pMenu').
 var mD = menuObj.menu[menuName][0];
 // Add timer and counter variables to the menu data structure, we'll
need them.
 if (!mD.timer) mD.timer = 0;
 if (!mD.counter) mD.counter = 0;
 with (mD)
 {
  // Stop any existing animation.
  clearTimeout(timer);
  // If the layer doesn't exist (cross-frame navigation) quit.
  if (!lyr || !lyr.ref) return;
  // Show the menu if that's what we're doing.
  if (dir>0) lyr.vis('visible');
  // Also raise showing layers above hiding ones.
  lyr.sty.zIndex = 1001 + dir;
  // Clip the visible area. Tweak this if you want to change
direction/acceleration etc.
  lyr.clip(0, 0, menuW+2,
(menuH+2)*Math.pow(Math.sin(Math.PI*counter/200),0.75) );
  // Remove clipping in NS6 on completion, seems to help old versions.
  if ((isDOM&&!isIE) && (counter>=100)) lyr.sty.clip='';
  // Increment the counter and if it hasn't reached the end (10 steps
either way),
  // set the timer to call the show/hide function again in 40ms.
  counter += dir;
  if (counter>100) counter = 100;
  else if (counter<0) { counter = 0; lyr.vis('hidden') }
  else timer =
setTimeout(menuObj.myName+'.'+(dir>0?'show':'hide')+'Menu("'+menuName+'")',
40);
 }
}
// Here's the alternative IE5.5+ filter animation function.
function menuFilterShow(menuObj, menuName, filterName)
{
 var mD = menuObj.menu[menuName][0];
 with (mD.lyr)
 {
  sty.filter = filterName;
  var f = ref.filters;
  if (f&&f.length&&f[0]) f[0].Apply();
  vis('visible');
  if (f&&f.length&&f[0]) f[0].Play();
 }
}
function addMenuBorder(mObj, iS, alpha, bordCol, bordW, backCol, backW)
{
 // Loop through the menu array of that object, finding matching
ItemStyles.
 for (var mN in mObj.menu)
 {
  var mR=mObj.menu[mN], dS='<div style="position:absolute; background:';
  if (mR[0].itemSty != iS) continue;
  // Loop through the items in that menu, move them down and to the
right a bit.
  for (var mI=1; mI<mR.length; mI++)
  {
   mR[mI].iX += bordW+backW;
   mR[mI].iY += bordW+backW;
  }
  // Extend the total dimensions of menu accordingly.
  mW = mR[0].menuW += 2*(bordW+backW);
  mH = mR[0].menuH += 2*(bordW+backW);
  // Set the menu's extra content string with divs/layers underneath the
items.
  if (isNS4) mR[0].extraHTML += '<layer bgcolor="'+bordCol+'" left="0"
top="0" width="'+mW+
   '" height="'+mH+'" z-index="980"><layer bgcolor="'+backCol+'"
left="'+bordW+'" top="'+
   bordW+'" width="'+(mW-2*bordW)+'" height="'+(mH-2*bordW)+'"
z-index="990"></layer></layer>';
  else mR[0].extraHTML += dS+bordCol+'; left:0px; top:0px;
width:'+mW+'px; height:'+mH+
   'px; z-index:980; '+(alpha!=null?'filter:alpha(opacity='+alpha+');
-moz-opacity:'+(alpha/100):'')+
   '">'+dS+backCol+'; left:'+bordW+'px; top:'+bordW+'px;
width:'+(mW-2*bordW)+'px; height:'+
   (mH-2*bordW)+'px; z-index:990"></div></div>';
 }
}
function addDropShadow(mObj, iS)
{
 // Pretty similar to the one above, just loops through list of extra
parameters making
 // dropshadow layers (from arrays) and extending the menu dimensions to
suit.
 for (var mN in mObj.menu)
 {
  var a=arguments, mD=mObj.menu[mN][0], addW=addH=0;
  if (mD.itemSty != iS) continue;
  for (var shad=2; shad<a.length; shad++)
  {
   var s = a[shad];
   if (isNS4) mD.extraHTML += '<layer bgcolor="'+s[1]+'" left="'+s[2]+'"
top="'+s[3]+'" width="'+
    (mD.menuW+s[4])+'" height="'+(mD.menuH+s[5])+'"
z-index="'+(arguments.length-shad)+'"></layer>';
   else mD.extraHTML += '<div style="position:absolute;
background:'+s[1]+'; left:'+s[2]+
    'px; top:'+s[3]+'px; width:'+(mD.menuW+s[4])+'px;
height:'+(mD.menuH+s[5])+'px; z-index:'+
    (a.length-shad)+'; '+(s[0]!=null?'filter:alpha(opacity='+s[0]+');
-moz-opacity:'+(s[0]/100):'')+
    '"></div>';
   addW=Math.max(addW, s[2]+s[4]);
   addH=Math.max(addH, s[3]+s[5]);
  }
  mD.menuW+=addW; mD.menuH+=addH;
 }
}
// Extra code for updating and moving the menus is embedded in the
feature list in the HTML document
//--></script>
<font face="Arial, Helvetica" size="2">
<center>
<br /><br />
<h2>Cascading Popup Menus v5.1</h2>
by Angus Turnbull -
<a href="
http://www.twinhelix.com
"
target="_blank">
http://www.twinhelix.com
</a>.
Updated: 3 September 2002.
</center>
<br />
<hr width="95%" />
<br />
<!-- Try uncommenting this line, and typing "pMenu" into the Go To
box... -->
<!-- <iframe src="jsobj.html" width="90%" height="400"></iframe> -->
<div style="padding: 10px">
<p>Sets up a system of multilevel popup menus on a page. Be sure to
check my site regularly
for compatibility information, Frequently Asked Questions and new
versions.
Features of this script include:</p>
<script language="JavaScript1.2"><!--
// Here's my demo code for tweaking and shifting the menu. Enjoy :).
// This illustrates changing the contents of the menu -- delete this,
it's unnecessary...
// This DOES NOT WORK in Opera yet (as of v6.00 at time of writing) by
the way.
function changeMenu() { with (pMenu)
{
 // If your modifications are quite extensive, probably hide the menu
before commencing
 // them, as the script relies on the menu array in realtime to handle
highlighting etc.
 //over('root', 0);
 //menu.root[0].lyr.vis('hidden');
 // Create a whole new menu...
 startMenu('mNewMenu', true, 0, 22, 130, subM);
 addItem('<b>TwinHelix Designs:</b><br>Extreme DHTML.<br>Small
Code.<br>Click to Visit...',
  'window.open("
http://www.twinhelix.com
")', 'js:', subM, 70);
 // Rebuild the existing root menu to change the text, and pop this out.
 startMenu('root', false, 10, 0, 17, hBar);
 addItem('&nbsp; Rebuilt &gt; &gt;', '#', '', hBar, 80);
 addItem('&nbsp; First', 'mFile', 'sm:', hBar, 50);
 addItem('&nbsp; Second', 'mEdit', 'sm:', hBar, 60);
 addItem('&nbsp; Third', 'mHelp', 'sm:', hBar, 50);
 addItem('&nbsp; Dynamism...', 'mNewMenu', 'sm:', hBar, 80);
 // Change a couple of items in the "File" menu, without rebuilding it.
 menu.mFile[1].text = 'New...';
 menu.mFile[4].text = 'Logoff<br />Menus...';
 // Call the update function to implement our changes.
 update();
}}
// This is just the moving command called when you click the feature
list.
function moveRoot()
{
 with (pMenu.menu.root[0].lyr) x( (x()<100) ? 100 : 10);
}
//--></script>
<ul>
 <li><b>Object-orientated</b> code for portability and <b>multiple
menus</b> if needed.</li>
 <li>Easy <b>constructor functions</b> setup the menu data
structure.</li>
 <li><b>Two menu creation modes</b> selectable by browser, 'Fast' is
used for IE, NS6 and Opera
  and 'Dynamic' for NS4.</li>
 <li><b>Dynamic menu update</b> mode allows menus to be <a
href="javascript:changeMenu()">changed
  after loading</a>.</li>
 <li><b>Fast creation mode</b> uses document.write() inline for speedy
creation.</li>
 <li><b>Freeform cross-frame support</b> built in.</li>
 <li>Each menu can be <b>horizontal or vertical</b>.</li>
 <li><b>Absolute or relative positioning</b> of menus - either specified
as a string or
  formula absolutely, or offset from trigger position on the fly.</li>
 <li>This means you can <a href="javascript:moveRoot()">move the root
menu</a>, and
  all the others will follow.</li>
 <li><b>Optional centring/scrolling with window</b> or any alignment
needed --
  menus can be easily positioned by calculating JavaScript
formulae/functions.</li>
 <li>Menus <b>don't have to overlap each other</b> thanks to adjustable
popup show and
  hide timeouts.</li>
 <li>Nearly unlimited <b>hierarchial menus</b> (popouts) -- as many
levels as needed.</li>
 <li>Popouts can show <b>on mouseover or on click</b>, set on a per-menu
basis.</li>
 <li>Automatically shows only <b>one hierarchy at a time</b> (like
Windows' menus).</li>
 <li>Items automatically <b>highlight through hierarchy</b> back to root
menu.</li>
 <li>Supports <b>hoverable background colours and images</b> throughout
hierarchy.</li>
 <li>Supports <b>hoverable alpha filtering</b> for translucent items in
IE/Win and NS6.</li>
 <li>Customisable <b>ItemStyle classes</b> allow you to pass each menu
and/or item a
  uniform appearance by altering colours, text styles, dimensions,
popout indicators,
  CSS borders etc...</li>
 <li>Arbitrary HTML can be added to menus, like example <b>dropshadows
and menu borders</b>.</li>
 <li>Supports <b>frame targets and JavaScript commands</b> in
items.</li>
 <li>You can <b>click anywhere</b> on items to activate them.</li>
 <li>Customisable <b>events applied to items</b> -- onmouseover,
onmouseout and onclick.</li>
 <li>Customisable <b>show and hide animations</b>, for example this
clipping animation.</li>
 <li><b>Small code</b> -- compacts down to only 13kb plus menu
definitions and setup/extras,
  which is several seconds to download on a good dial-up modem, so your
visitors won't be
  kept waiting.</li>
</ul>
<br />
<h4>Conditions of Use:</h4>
<ol>
 <li>This script is provided as-is, without a warranty of any kind, as
although I strive
  to make it as compatible as possible I cannot guarantee it will work
in all target
  environments, so test thoroughly.</li>
 <li>You may not redistribute this in any form, either intact or
modified, without my consent.</li>
 <li>On sites that use this script, you should place a visible link to
the splash page of my
  site, with a short description, for example:
  "<a href="
http://www.twinhelix.com
" target="_blank">DHTML / JavaScript
provided by
  TwinHelix Designs</a>". (Please don't link to individual pages within
this site as my splash
  page detects browser capabilities). Also leave the my 'script name'
comment in the source.
  These stop interested users emailing the webmaster asking how to
acquire the scripts.
  If linking me doesn't suit your project...</li>
 <li><b>COMMERCIAL USERS:</b> This script is 'donation-ware'. If you
want to support this script
  and/or you are using this script as part of a commercial project,
please consider
  <a href="
http://www.twinhelix.com
">making a donation</a> via my site.
After all, I
  have probably saved you several months developing, debugging and
documenting a comparable script.
  Donors may take an optional exemption from a 'visible link' on the
site, if that does not
  fit your site design.</li>
</ol>
<br />
<h4>Usage Instructions:</h4>
<p>Most of the instructions are already in the source -- open this up
with your favourite text
editor and start customising. Before deploying this on your site, be
sure to remove the comments!
You can double or treble loading speed that way -- there's a handy
utility from my site to
assist with this as well.</p>
<p>See my site for Frequently Asked Questions if you're stuck,
compatibility information and new
versions. Basically, to use this script cut and paste the script element
and stylesheet into your
page. You may wish to make the script element at least an external .JS
file, which should
speed loading times as people navigate; possibly do the same with the
stylesheet.</p>
<p><i>Good luck! -- Angus</i></p>
<br><h4>Version History:</h4>
<ul>
 <li>v5.1:
  <ul>
   <li>Menu positioning routine upgraded. Now, it's much faster (only
repositions visible
    menus as needed) and can reposition layers of relative menus on
scroll.</li>
   <li>Relatively positioned menus now always show within window
borders.</li>
   <li>You can now specify mouse cursors to use in the ItemStyles (2
extra parameters).</li>
   <li>Example shiny new alpha fading animation for IE5.5+ on Windows,
commented in the
    animation function, and a DXImageTransform filters example too. The
animation is now
    disabled by default in Mozilla versions prior to 1.0 (such as
NS6).</li>
   <li>Item positions and dimensions are now calculated by the addItem()
command instead of
    the update function.</li>
   <li>Added 'extraHTML' property to menu data tree, allowing you to
insert arbitrary HTML
    strings into the menu container layers.</li>
   <li>Combining the above two points, I've included demo functions to
extend the menu with
    semitranslucent dropshadows and whole-menu borders, and
reposition/curve menu items.</li>
   <li>Rewrote parts of crossframe code, now doesn't show JS errors when
documents are loaded
    outside the menu, and should support more flexible nested
framesets/windows.</li>
   <li>You can specify custom 'oncreate' events for menus to customise
appearance further.</li>
   <li>Added ability to show submenus on click rather than on mouseover
if desired.</li>
   <li>Some tweaks to the cross-browser code section, including a
detection of strict doctypes
    and/or strict CSS1 compliance to improve IE6/NS6 compatibility.</li>
   <li>Fixed bug in Opera 5/6 with IE emulation mode turned off.</li>
   <li>Fixed function-in-function in NS4.05, and also tweaked popClick()
function for very new
    Mozilla betas/NS7 pre-release -- now it's passed parameters instead
of using overM/I.</li>
   <li>Random internal tweaks and polish ups, a whole load of comment
reorganising, and changed
    the default colour scheme to make it bearable :).</li>
  </ul>
 </li>
 <li>v5.0:
  <ul>
   <li>Added multiple menu creation modes for better browser
compatibility, the script now works
    in Opera! Not all features are available there, but the menu should
show.</li>
   <li>Moved the menu script to the BODY of the page as browsers that
use Fast mode call
    document.write() to create their menus.</li>
   <li>Menu animation! Example clipping effect has been added to the
'Optional Code' section,
    with a corresponding architectural change, now the menu calls show
and hide functions that
    you override with special functions like these.</li>
   <li>Recorded dimensions and visibility of menus as part of the menu
object.</li>
   <li>Rewrote part of the over() routine to handle animating menus more
reliably that don't
    show/hide instantaneously, also reducing unneccessary hide calls so
large menus should be
    more responsive.</li>
   <li>Built in some more internal error-checking so non-existant menu
names should not stop the
    display of the root menu, to make debugging typos easier.</li>
   <li>Completely reorganised the documentation/example, more modular
and easier to follow now...
    hopefully...</li>
   <li>Rewrote the cross-frame .JS file for clarity and to support new
creation modes.</li>
   <li>Rewrote events section, hopefully less confusing.</li>
   <li>Also tweaked NS4 resize bug handler.</li>
   <li>v5.01 Maintenance Release: Changed sample animation code to
remove JS error in
    cross-frames usage and set Z-Indices to raise showing layers above
hiding ones.</li>
  </ul>
 </li> 
 <li>v4.1:
  <ul>
   <li>Gave into temptation and added alpha filtering routines ;). Now
your menus can be
    semi-transparent under IE/Windows or NS6.</li>
   <li>Added ability to override any options of the ItemStyles for
individual items.</li>
   <li>Added my page object to easily detect document properties and
slim down subframe/event
    capturing code.</li>
   <li>Set cursor to hand/pointer only for items with actions. Blank
items and 'sm:' items now
    have a regular arrow when moused over in IE4+/NS6, others have the
'hand' cursor.</li>
   <li>Fixed small, non-fatal JS error that happened in cross-frame
scripts with pages not
    fully loaded sometimes.</li>
   <li>The usual tweaks to the example, comments, and cross-browser
code.</li>
   <li>v4.11 maintenance release: Fixed scrolling with window without
frameset code enabled
    in Netscape. D'oh!</li>
  </ul>
 </li>
 <li>v4.0:
  <ul>
   <li>Added freeform cross-frame support! Now you can specify a parent
window (or layer) in
    which each menu is to be created with the startMenu() call.</li>
   <li>Clarified usage of positioning formulae. Now, whenever you
specify a number as a position
    of a menu it is offset from its parent, otherwise it is positioned
absolutely on the page for
    formulae/strings -- for example, menus in other frames need absolute
positioning.</li>
   <li>Added 'Fast Create' mode for large menus. Now you can optionally
create only the root
    menu initially, and other menus are created only when shown -- can
speed load times.</li>
   <li>Added ability to change border classes on mouseover to
ItemStyles.</li>
   <li>Made NS4 call the over event when you mouseover the text within
menus. Should help
    people trying to assign status messages using menu events.</li>
   <li>Changed the 'events' introduced in v3.1. Instead of assigning
events to each item, you
    now assign one handler function to the entire menu, which gets
called for every item.</li>
   <li>Added option to disable menu hiding once shown, for permanently
visible menus.</li>
   <li>Loads and loads of other tweaks, and updates to the
comments.</li>
  </ul>
 </li>
 <li>v3.1:
  <ul>
   <li>Changed the way clicks are detected on menu items. Now, it uses
document.onclick
    globally rather than per item, which seemed to have the occasional
problem in NS4 under
    Windows 2000.</li>
   <li>Added support for changable background images as well as colours
for items.</li>
   <li>Added support for optional, customisable menu delays for both
showing and hiding.
    That means you can stop rapid mouseovers showing menus, if you
want.</li>
   <li>Added an example 'scroll-with-window' extension to the menu.</li>
   <li>Added 'events' for each item. Now, you can specify a Javascript
function when an item
    moused over/out, or clicked. Useful for adding click events to 'sm:'
items...?</li>
   <li>Changed the cross-browser code to support my new layer functions
that can work across
    frames...</li>
   <li>Made borderless items 1px larger, removing border overlap
spacing.</li>
  </ul>
 </li>
 <li>v3.0:
  <ul>
   <li>Where do I start...? OK, the whole script is now
object-orientated. That means you can
    have several independent menus on one page using the one set of
functions.</li>
   <li>Totally rewrote the menu data structure, now using smaller
constructor functions.</li>
   <li>Menus are now named, not numbered, for that personal touch
:).</li>
   <li>Added the new ItemStyles feature for assigning colours and
styles, and easier upgrades
    in future -- colours etc. are now defined outside the menu item
creation section as JS
    objects and passed to the menu constructors, like CSS classes.</li>
   <li>Added support for a much-requested feature: text styles change on
mouseover.</li>
   <li>Menu creation is now fully dynamic. You can recreate menus
anytime after changing
    properties, for example adding or removing menus on the fly without
reloading.</li>
   <li>Included my new Layer API to make this script smaller when
combined with other scripts
    like the scroller, as they can share useful functions like
moving/colouring etc.</li>
   <li>Transparent background colours for items are now supported.</li>
   <li>Combined several functions into one 'popOver' function, including
the new lightup routine
    that can change text styles and lessens flicker as items are
highlighted.</li>
   <li>Support for JavaScript formulae as menu positions -- for example,
to centre the menu.</li>
   <li>You can now position the popout indicator how you want, aligned
to either edge of an item.</li>
   <li>Loads and loads of other changes and tweaks.</li>
  </ul>
 </li>
 <li>v2.3:
  <ul>
   <li>Rewrote the hierarchy tree calculator function as NS4.05 and
earlier threw an error
    when they encountered a return within a while(1) loop.</li>
   <li>Changed the way the construction functions parse input, reducing
file size further.</li>
   <li>Tweaked the example and comments slightly, as per usual...</li>
   <li>v2.31 maintenance release: Fix for NS4/Mac related to the
optional centring function causing
    page reloads.</li>
  </ul>
 </li>
 <li>v2.2:
  <ul>
   <li>Fixed a sneaky bug in some versions of NS4 when it refused to
evaluate a link to
    'javascript:' and instead set it as the page location. Some things
you think the NS
    development team would realise before releasing their
browsers...</li>
   <li>Cosmetic fixes: altered padding slightly in NS4, added z-indices
of 1000 in all
    browsers, and stopped NS6 displaying menus slightly larger than
intended.</li>
   <li>Also defined width of items in IE/NS6, that means including
&lt;center&gt; tags
    in your item text should work again.</li>
   <li>A simple feature I should have included before: menus don't have
to be sequentially
    numbered now.</li>
   <li>The usual minor tweaks in the comments and functions, no menu[]
array changes.</li>
  </ul>
 </li> 
 <li>v2.1:
  <ul>
   <li>Made IE5 use the DHTML object model rather than the DOM to
improve IE5/Mac
    compatibility slightly.</li>
   <li>Speed increase by ditching tables in favour of nested divs/layers
in IE/NS6.</li>
   <li>You can now specify how much padding you want between item
borders and text.</li>
   <li>All links are now JavaScript-based, and you can target any frame
or JS function.</li>
   <li>You can now click anywhere on the menu items to activate
them!</li>
   <li>Included an example function to centre the menus, due to popular
demand :).</li>
   <li>Captured onLoad and onResize in the script, now no parameters to
the BODY tag need
    to be specified. You can still specify them there if you want,
though.</li>
   <li>Added another example item constructor to allow you to create
multicoloured items in
    a menu. See the 'Reopen' menu above for an example.</li>
   <li>Specified dimensions for items in IE, hopefully prevents IE4 from
displaying
    scrollbars where it shouldn't.</li>
   <li>Loads of other small updates to code, comments, readme etc.</li>
  </ul>
 </li>  
 <li>v2.0:
  <ul>
   <li>Basically recoded the menu creation routine from the ground up.
Now menus are created
    dynamically after the document loads, improving NS4
compatibility.</li>
   <li>Added support for creating horizontal menus automatically and
removed the 'custom
    root menu' feature. Now any menu can be horizontal (not just the
root).</li>
   <li>Recoded sections using W3C DOM methods to access elements, for
NS6 compliance.</li>
   <li>Added a NS4 window resize handler to reload the page when window
resized
    horizontally, as NS4 has major problems with DHTML and
resizing.</li>
   <li>Menu references are now built into the menu array e.g.
menu[0][0].ref, so ID's are
    no longer necessary.</li>
   <li>Frame targets added to the menu array separately, since so many
people seem to be
    using them. So tweaking the URL for additional attributes is no
longer necessary.</li>
   <li>Popout indicators can now be specified for each menu
individually.</li>
   <li>Borders are now specified via stylesheet classes you can add to
the menu array.</li>
   <li>Tweaked many small things, e.g. root menu items that don't target
menus now dim
    instantaneously when you mouseout.</li>
  </ul>
 </li>
 <li>v1.1:
  <ul>
   <li>Added support for stylesheets for each individual menu.</li>
   <li>Split the item height to table height and spacing, more reliable
that way</li>
   <li>Fixed bug in IE4 when menus weren't stretched properly. The fix
was to change a zero
     to a three halfway through the code :).</li>
   <li>Updated comments and extended example slightly.</li>
   <li>Tidied up internal operation a little bit, should display faster
now.</li>
  </ul>
 </li>
 <li>v1.0:
  <ul><li>Initial public release.</li></ul>
 </li>
</ul>
<br><h4>Known Issues / Future Plans:</h4>
<p>This script should run in Opera, with 'run' being the operative word.
Opera's HTML/CSS support
is pretty good, but its JavaScript/DHTML engine is <i>extremely</i>
limited compared to more
'standards-compliant' browsers like IE and NS6 ;). The menus should
show, but don't expect
animation/dynamic updates or text colour/border/translucency changes in
Opera 5 or 6. Opera 5
also seems to ignore ItemStyle padding, but Opera 6 is OK. Transparent
background colours
also seem to be an issue, and background image changing is unsupported
by Opera 5. If you
think Opera users might frequent your site, be sure to test your menu
out thoroughly!</p>
<p>Netscape 6 still has a few nasty bugs that can rear their head
sometimes. If the contents
of your items are bigger than the items themselves, occasionally it
doesn't hide menus properly...
sections remain onscreen after mouseout. So make sure your items are
large enough for anything that
they will contain! This also happens occasionally with transparent
background colours...
your mileage may vary on this one. As always, test thoroughly!</p>
<p>Text style changes may induce a little flicker in Netscape 4 as the
layer contents have to be
rewritten -- other browsers are OK for this as they allow manipulation
of classes through the DOM.
Also, the cursor changes from a hand to a pointer over the menus in NS4.
This isn't a bug as
such, you can still click anywhere to activate them. You just can't
specify stylesheet cursors in
NS4.</p>
<p>'Future Plans' is a little misleading as I'm suffering from
scripter's block ;). Suggestions are
always welcome...</p>
</div>
</font>
</body>
</html>
<!-- Well done for reading this far! ;). -->


Aspetto che lo imparo a memoria e ti dico

 Aspetto che lo imparo a memoria e ti dico


 Simpatico :)
Eh, pero' ha ragione!
Ma ti rendi conto che hai inviato 58KB di codice! Secondo me hai fatto un
record :)