By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,081 Members | 2,118 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,081 IT Pros & Developers. It's quick & easy.

Cascading menu script

P: n/a
Below is a script I found at http://javascript.internet.com/ for a
cascading menu. The script works great but there is one thing that I
would like modified. BecauseI am just learning javascript, I did not
want to try to modify the code without a little help. When you place
the mouse over the menu bar, this script calls the function to show the
menu. I would like it modified to hide the menu when the mouse is
removed. Please help. The full code is below:

function InitMenu()
{
var bar = menuBar.children

for(var i=0;i < bar.length;i++)
{
var menu=eval(bar[i].menu)
menu.style.visibility = "hidden"
bar[i].onmouseover = new Function("ShowMenu("+bar[i].id+")")
var Items = menu.children
for(var j=0; j<Items.length; j++)
{
var menuItem = eval(Items[j].id)

if(menuItem.menu != null)
{
menuItem.innerHTML += "<Span
Id="+menuItem.id+"_Arrow class='Arrow'>4</Span>"
//var tmp = eval(menuItem.id+"_Arrow")
// tmp.style.pixelLeft =
menu.getBoundingClientRect().Right //- tmp.offsetWidth - 15
FindSubMenu(menuItem.menu)}

if(menuItem.cmd != null)
{
menuItem.onclick = new
Function("Do("+menuItem.id+")") }

menuItem.onmouseover = new
Function("highlight("+Items[j].id+")")

}

}
}
function FindSubMenu(subMenu)
{
var menu=eval(subMenu)
var Items = menu.children
for(var j=0; j<Items.length; j++)
{
menu.style.visibility = "hidden"
var menuItem = eval(Items[j].id)
if(menuItem.menu!= null)
{
menuItem.innerHTML += "<Span
Id="+menuItem.id+"_Arrow class='Arrow'>4</Span>"
// var tmp = eval(menuItem.id+"_Arrow")
//tmp.style.pixelLeft = 35
//menuItem.getBoundingClientRect().right - tmp.offsetWidth - 15
FindSubMenu(menuItem.menu)
}

if(menuItem.cmd != null)
{
menuItem.onclick = new
Function("Do("+menuItem.id+")") }

menuItem.onmouseover = new
Function("highlight("+Items[j].id+")")

}
}
function ShowMenu(obj)
{
HideMenu(menuBar)
var menu = eval(obj.menu)
var bar = eval(obj.id)
bar.className="barOver"
menu.style.visibility = "visible"
menu.style.pixelTop = obj.getBoundingClientRect().top +
obj.offsetHeight + Bdy.scrollTop
menu.style.pixelLeft = obj.getBoundingClientRect().left +
Bdy.scrollLeft
}

function highlight(obj)
{
var PElement = eval(obj.parentElement.id)
if(PElement.hasChildNodes() == true)
{ var Elements = PElement.children
for(var i=0;i<Elements.length;i++)
{
TE = eval(Elements[i].id)
TE.className = "menuItem"
}
}
obj.className="ItemMouseOver"
window.defaultStatus = obj.title
ShowSubMenu(obj)
}

function Do(obj)
{
var cmd = eval(obj).cmd
window.navigate(cmd)

}

function HideMenu(obj)
{
if(obj.hasChildNodes()==true)
{
var child = obj.children

for(var j =0;j<child.length;j++)
{
if (child[j].className=="barOver")
{var bar = eval(child[j].id)
bar.className="Bar"}

if(child[j].menu != null)
{
var childMenu = eval(child[j].menu)
if(childMenu.hasChildNodes()==true)
HideMenu(childMenu)

childMenu.style.visibility = "hidden"
}
}

}
}
function ShowSubMenu(obj)
{
PMenu = eval(obj.parentElement.id)
HideMenu(PMenu)
if(obj.menu != null)
{
var menu = eval(obj.menu)
menu.style.visibility = "visible"
menu.style.pixelTop = obj.getBoundingClientRect().top +
Bdy.scrollTop
menu.style.pixelLeft = obj.getBoundingClientRect().right +
Bdy.scrollLeft
if(menu.getBoundingClientRect().right window.screen.availWidth )
menu.style.pixelLeft = obj.getBoundingClientRect().left -
menu.offsetWidth
}
}

Jan 20 '07 #1
Share this Question
Share on Google+
1 Reply


P: n/a

Anthony wrote:
Below is a script I found at http://javascript.internet.com/ for a
cascading menu. The script works great but there is one thing that I
would like modified. BecauseI am just learning javascript, I did not
want to try to modify the code without a little help. When you place
the mouse over the menu bar, this script calls the function to show the
menu. I would like it modified to hide the menu when the mouse is
removed. Please help. The full code is below:

function InitMenu()
{
var bar = menuBar.children

for(var i=0;i < bar.length;i++)
{
var menu=eval(bar[i].menu)
menu.style.visibility = "hidden"
bar[i].onmouseover = new Function("ShowMenu("+bar[i].id+")")
var Items = menu.children
for(var j=0; j<Items.length; j++)
{
var menuItem = eval(Items[j].id)

if(menuItem.menu != null)
{
menuItem.innerHTML += "<Span
Id="+menuItem.id+"_Arrow class='Arrow'>4</Span>"
//var tmp = eval(menuItem.id+"_Arrow")
// tmp.style.pixelLeft =
menu.getBoundingClientRect().Right //- tmp.offsetWidth - 15
FindSubMenu(menuItem.menu)}

if(menuItem.cmd != null)
{
menuItem.onclick = new
Function("Do("+menuItem.id+")") }

menuItem.onmouseover = new
Function("highlight("+Items[j].id+")")

}

}
}
function FindSubMenu(subMenu)
{
var menu=eval(subMenu)
var Items = menu.children
for(var j=0; j<Items.length; j++)
{
menu.style.visibility = "hidden"
var menuItem = eval(Items[j].id)
if(menuItem.menu!= null)
{
menuItem.innerHTML += "<Span
Id="+menuItem.id+"_Arrow class='Arrow'>4</Span>"
// var tmp = eval(menuItem.id+"_Arrow")
//tmp.style.pixelLeft = 35
//menuItem.getBoundingClientRect().right - tmp.offsetWidth - 15
FindSubMenu(menuItem.menu)
}

if(menuItem.cmd != null)
{
menuItem.onclick = new
Function("Do("+menuItem.id+")") }

menuItem.onmouseover = new
Function("highlight("+Items[j].id+")")

}
}
function ShowMenu(obj)
{
HideMenu(menuBar)
var menu = eval(obj.menu)
var bar = eval(obj.id)
bar.className="barOver"
menu.style.visibility = "visible"
menu.style.pixelTop = obj.getBoundingClientRect().top +
obj.offsetHeight + Bdy.scrollTop
menu.style.pixelLeft = obj.getBoundingClientRect().left +
Bdy.scrollLeft
}

function highlight(obj)
{
var PElement = eval(obj.parentElement.id)
if(PElement.hasChildNodes() == true)
{ var Elements = PElement.children
for(var i=0;i<Elements.length;i++)
{
TE = eval(Elements[i].id)
TE.className = "menuItem"
}
}
obj.className="ItemMouseOver"
window.defaultStatus = obj.title
ShowSubMenu(obj)
}

function Do(obj)
{
var cmd = eval(obj).cmd
window.navigate(cmd)

}

function HideMenu(obj)
{
if(obj.hasChildNodes()==true)
{
var child = obj.children

for(var j =0;j<child.length;j++)
{
if (child[j].className=="barOver")
{var bar = eval(child[j].id)
bar.className="Bar"}

if(child[j].menu != null)
{
var childMenu = eval(child[j].menu)
if(childMenu.hasChildNodes()==true)
HideMenu(childMenu)

childMenu.style.visibility = "hidden"
}
}

}
}
function ShowSubMenu(obj)
{
PMenu = eval(obj.parentElement.id)
HideMenu(PMenu)
if(obj.menu != null)
{
var menu = eval(obj.menu)
menu.style.visibility = "visible"
menu.style.pixelTop = obj.getBoundingClientRect().top +
Bdy.scrollTop
menu.style.pixelLeft = obj.getBoundingClientRect().right +
Bdy.scrollLeft
if(menu.getBoundingClientRect().right window.screen.availWidth )
menu.style.pixelLeft = obj.getBoundingClientRect().left -
menu.offsetWidth
}
}
General notes on first glance:

1. This script will only work on Internet Explorer, because it uses the
IE-specific DOM. Use element attributes node.childNodes and
node.parentNode instead of IE-specific node.children and
node.parentElement.

2. I'm not sure why this script uses "eval" so much. It would appear
that it's attempting to use "eval" to parse attributes to strings? It
doesn't really make any sense. In general (read this group's FAQ), you
want to avoid using eval wherever possible, and I'm not convinced that
this script needs to use eval at all. -- Ok, after looking at this
script more closely, I see why it's using eval. It's another IE-only
thing: IE has a JS reference to each node with an ID attribute with the
variable name of that ID. So for instance, <div id="menu"will be a
JS variable called "menu". No other browser supports this, that I'm
aware of, so you should replace "eval" with document.getElementById.

3. Lots and lots of mediocre scripts and textbooks out there show code
like "node.style.visibility = 'hidden'" and
"node.className='something'". This works ok with smaller scripts but
you'll quickly run into trouble on complex websites where nodes have
many classnames. It's best to have helper functions that will add or
remove classnames without setting the "className" property, thereby
overwriting whatever other classes the element might have. Also, just
a personal preference, but I like to avoid assigning any "style"
properties on elements except for positioning. Use classes for
everything else, like color, visibility, border, etc.

4. Forget that website. Remove it from your bookmarks, forget it even
exists. Most of the scripts there are ancient and have horrible coding
practices, like only writing for one browser. When you're learning
don't just read "random scripts you found somewhere on the Internet,"
you need good reliable resources you can trust. Pick up a copy of
javascript: The Definitive Guide published by O'Reilly Press (the one
with the rhino on the cover). Read through that, work through some
examples, then let us know if you're still having problems with your
code.

Best,

-DG

Jan 21 '07 #2

This discussion thread is closed

Replies have been disabled for this discussion.