...

View Full Version : Submenus not playing nice.



WillGibson
12-17-2004, 09:01 PM
I've been playing about with JS menus for a few days and trying to put my own together. I know there are lots of ones out there for download but I find I learn more doing it myself. :D

This works ok if each parent has only one child menu. "Sub-Menu Item 102" and "Sub-Menu Item 103" both have a child menu but only the top one (Sub-Menu Item 102) displays. I can't seem to see why. A fresh pair of eyes is welcome.

As always, I code only for IE. Please pardon the code, it is very unfinished atm.


<html>
<head>
<title>Playground, JS Menus</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<script language="javascript">
arySubMenu03 = [[0,"Sub-Menu Item 301", "Tooltip for this item.", false, "fSM301OnClick()", null, false, 0, 0, 0],
[1,"Sub-Menu Item 302", "Tooltip for this item.", false, "fSM302OnClick()", null, false, 0, 0, 0],
[2,"Sub-Menu Item 303", "Tooltip for this item.", false, "fSM303OnClick()", null, false, 0, 0, 0]];
arySubMenu02 = [[0,"Sub-Menu Item 201", "Tooltip for this item.", false, "fSM201OnClick()", null, false, 0, 0, 0],
[1,"Sub-Menu Item 202", "Tooltip for this item.", false, "fSM202OnClick()", null, false, 0, 0, 0],
[2,"Sub-Menu Item 203", "Tooltip for this item.", false, "fSM203OnClick()", null, false, 0, 0, 0],
[3,"Sub-Menu Item 204", "Tooltip for this item.", false, "fSM204OnClick()", null, false, 0, 0, 0],
[4,"Sub-Menu Item 205", "Tooltip for this item.", false, "fSM205OnClick()", null, false, 0, 0, 0],
[5,"Sub-Menu Item 206", "Tooltip for this item.", false, "fSM206OnClick()", null, false, 0, 0, 0]];
arySubMenu01 = [[0,"Sub-Menu Item 101", "Tooltip for this item.", false, "fSM101OnClick()", null, false, 0, 0, 0],
[1,"Sub-Menu Item 102", "Tooltip for this item.", true, "", arySubMenu03, false, 0, 0, 0],
[2,"Sub-Menu Item 103", "Tooltip for this item.", true, "", arySubMenu02, false, 0, 0, 0]];
arySubMenu00 = [[0,"Master Menu Item 001", "Tooltip for this item.", false, "fSM001OnClick()", null, false, 0, 0, 0],
[1,"Master Menu Item 002", "Tooltip for this item.", false, "fSM002OnClick()", null, false, 0, 0, 0],
[2,"Master Menu Item 003", "Tooltip for this item.", true, "", arySubMenu01, false, 0, 0, 0],
[3,"Master Menu Item 004", "Tooltip for this item.", false, "fSM004OnClick()", null, false, 0, 0, 0]];
aryRootMenu = [[0,"Menu", "Tooltip for this item.", true, "", arySubMenu00, false, 0, 0, 0]];

strRootID = "m0";
timeOnAllMenus = null;
timeOnSubMenu = null;

function fstrGetParentID(strID) {
strPID = "";
arystrBreakDown = strID.split("_");
for (i=0;i<arystrBreakDown.length-1;i++) {
strPID += arystrBreakDown[i];
if ((i+1) != (arystrBreakDown.length-1)) {
strPID += "_";
}
}
return strPID;
}

function fintGetElementNumber(strID) {
arystrBreakDown = strID.split("_");
intENum = 0;
if (arystrBreakDown.length > 1) intENum =(arystrBreakDown[arystrBreakDown.length-1] - 0);
return intENum;
}

function fDisplayMenus(strIDRoot, aryMenuRoot) {
for (i=0;i<aryMenuRoot.length;i++) {
objMenu = document.getElementById(strIDRoot+"_"+i);
if (objMenu) {
objMenu.style.visibility = ((aryMenuRoot[i][6])?"visible":"hidden");
if (aryMenuRoot[i][3]) {
fDisplayMenus(objMenu.id, aryMenuRoot[i][5]);
}
}
}
}
function fHideAllMenus() {
fSetAllNotVisible(aryRootMenu);
fDisplayMenus(strRootID, aryRootMenu);
}

function fSetAllNotVisible(aryMenuRoot) {
for (i=0;i<aryMenuRoot.length;i++) {
aryMenuRoot[i][6] = false;
if (aryMenuRoot[i][3]) {
fSetAllNotVisible(aryMenuRoot[i][5]);
}
}
}

function fSetChainVisible(strID, aryMenuRoot) {
arystrBreakDown = strID.split("_");
aryMenuCurr = aryMenuRoot;
for (i=1;i<arystrBreakDown.length;i++) {
aryMenuCurr[arystrBreakDown[i]][6] = true;
aryMenuCurr = aryMenuCurr[arystrBreakDown[i]][5];
}
}

function fMoveSubMenu(strID) {
objMenu = document.getElementById(strID);
if (objMenu) {
if (strID != strRootID) {
objParent = document.getElementById(fstrGetParentID(strID));
if (objParent) {
// Align the sub-menu to the parent...WRG
objMenu.style.top = (objParent.offsetTop + (22 * (fintGetElementNumber(objMenu.id)-0))) + 'px';
objMenu.style.left = (objParent.offsetWidth + objParent.offsetLeft) + 'px';
}

}
}
}

function fShowSubMenu(strID) {
clearTimeout(timeOnAllMenus);
fSetAllNotVisible(aryRootMenu);
fMoveSubMenu(strID);
fSetChainVisible(strID, aryRootMenu);
fDisplayMenus(strRootID, aryRootMenu);
}

function fHideSubMenu(strID) {
//alert(strID)
//fSetAllNotVisible(aryRootMenu);
//fSetChainVisible(fstrGetParentID(strID), aryRootMenu);
//timeOnSubMenu = setTimeout("fSetAllNotVisible(aryRootMenu);fSetChainVisible(fstrGetParentID('"+strID+"'), aryRootMenu)", 500);
}

function fShowMenu() {
clearTimeout(timeOnAllMenus);
//fDisplayMenus(strRootID, aryRootMenu);
}

function fHideMenu() {
timeOnAllMenus = setTimeout("fHideAllMenus()", 250);
}

function fCreateMenuLayer(strID, aryMenu, boolVisible, intLeft, intTop, intWidth) {
// Create the menu layer...WRG
document.write("<div id=\"" + strID + "\" style=\"left:"+intLeft+"px; top:"+intTop+"px; width:"+intWidth+"px; z-index:0; position:absolute; visibility:"+(boolVisible?"visible":"hidden")+"; border-style:none\" onMouseOver=\"fShowMenu()\" onMouseOut=\"fHideMenu()\">")
document.write("<table width=100% border=\"0\" bgcolor=\"#003366\" cellspacing=\"0\" cellpadding=\"0\">");
document.write("<tr><td>");
document.write("<table border=\"0\" cellspacing=\"1\" cellpadding=\"1\">");
for (i=0;i<aryMenu.length;i++) {
document.write("<tr><td "+(((intWidth-0)>0)?"":"nowrap")+" style=\"color:#FFFF00\" "+(aryMenu[i][3]?"onMouseOver=\"fShowSubMenu('"+strID+"_"+i+"')\" onMouseOut=\"fHideSubMenu('"+strID+"_"+i+"')\"":"")+((aryMenu[i][4] != "")?" onClick=\""+aryMenu[i][4]+"\"":"")+">"+aryMenu[i][1]+"</td></tr>");
}
document.write("</table>");
document.write("</td></tr>");
document.write("</table>");
document.write("</div>");

// Create any child menus...WRG
for (i=0;i<aryMenu.length;i++) {
if (aryMenu[i][3]) {
fCreateMenuLayer(strID+"_"+i, aryMenu[i][5], aryMenu[i][6], aryMenu[i][7], aryMenu[i][8], aryMenu[i][9]);
}
}
}

fCreateMenuLayer(strRootID, aryRootMenu, true, 25, 25, 50);

</script>
<td></td>
</body>
</html>

codegoboom
12-18-2004, 12:30 AM
That's a tad vague... can you narrow the problem area down to one function, or is the whole script in question?

WillGibson
12-18-2004, 04:09 AM
Well, the behavior that I see only happens with a menu having 2 (or more) child menus. The first one selected will display normally, while the following menu will not. It's easier to see the problem then to explain it.

If you run the example and open the menu to "Sub-Menu Item 102" you will see a child menu open. But if you then move down to "Sub-Menu Item 103", which also has a child menu, it will not open. The reverse is true also, start with "Sub-Menu Item 103" and it will open while "Sub-Menu Item 102" will not.

I think the problem is with the events onMouseOver and/or onMouseOut. They fire fShowSubMenu() and fHideSubMenu(). I'm having some problems locking down what the issue is but I think it is in this area. Of course I maybe totally off in the wrong place but that is what I think.

I hope that helps. If you need more just let me know.

Thank you

codegoboom
12-18-2004, 05:19 AM
Reducing the code to a minimal test-case may help in resolving the problem-areas; you know: building upon what works & all that.

just a suggestion :)

WillGibson
12-21-2004, 08:24 PM
I got it. It turned out to be problems with recursion.

I have not, until now, had any need to use recursion in Javascript. You have to be more careful with variables and make correct use of VAR or recursion may not function as you want it to.

Just an FYI post for anyone that may run into something like it. :thumbsup:

Thanks for the suggestions

codegoboom
12-23-2004, 04:27 AM
As the saying goes... To know recursion, one must first know recursion. :confused: ;)



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum