Recommendations for JavaScript drop-down menu code

B

Brian Adkins

I would appreciate recommendations for JavaScript code that implements
drop-down, hierarchical menus. Are there high quality libraries for
this, or is it more typical for people to roll their own?

My preference is for open source code, but royalty-free commercial
code would be acceptable as well.

Ideally, the code would:
* Allow configuring horizontal or vertical menus
* Allow configuring the delay for closing the menu after mousing out
of the menu
* Provide a mechanism for playing well with existing code and other
libraries
* Be well designed & documented
* Be highly portable among browsers in common use
* Allow styling via css

Thanks,
Brian Adkins
 
D

David Mark

I would appreciate recommendations for JavaScript code that implements
drop-down, hierarchical menus. Are there high quality libraries for
this, or is it more typical for people to roll their own?

I don't know if there are any good ones out there, but there are lots
of bad ones.
My preference is for open source code, but royalty-free commercial
code would be acceptable as well.

Ideally, the code would:
* Allow configuring horizontal or vertical menus

That is a function of CSS, not script.
* Allow configuring the delay for closing the menu after mousing out
of the menu

That doesn't make sense to me for a hierarchical menu.
* Provide a mechanism for playing well with existing code and other
libraries
* Be well designed & documented
* Be highly portable among browsers in common use

Your expectations of freebie menu scripts are likely too high.
* Allow styling via css

You'd be hard-pressed to disallow CSS with script.

Anyway, craate your hierarchy with nested lists, style it with CSS and
then look for a script that initially hides all but the parent list
and then displays child lists in response to mouse or keyboard input
(you'll find that most ignore the keyboard.)
 
B

Brian Adkins

That is a function of CSS, not script.

There are a number of ways of accomplishing this. CSS is one way, but
the JavaScript code can make CSS styling less difficult or more
difficult.
That doesn't make sense to me for a hierarchical menu.

It makes even more sense for a hierarchical menu. Consider navigating
through a complicated menu structure via hovering, then right before
you click the appropriate entry, you accidentally move the mouse too
far and the whole menu closes. That's the scenario (typically found on
CSS-only menus) I want to avoid, so I'd like a "grace period" if you
will.
Your expectations of freebie menu scripts are likely too high.

If so, then a commercial solution would seem to make sense. Do you
know of good commercial menus?
You'd be hard-pressed to disallow CSS with script.

Anyway, craate your hierarchy with nested lists, style it with CSS and
then look for a script that initially hides all but the parent list
and then displays child lists in response to mouse or keyboard input
(you'll find that most ignore the keyboard.)

If I was only looking for that, I'd just write it myself, but I'm not
big on reinventing wheels.
 
D

David Mark

There are a number of ways of accomplishing this. CSS is one way, but
the JavaScript code can make CSS styling less difficult or more
difficult.

How so? Your app must not break down when either or both is disabled.
It makes even more sense for a hierarchical menu. Consider navigating
through a complicated menu structure via hovering, then right before
you click the appropriate entry, you accidentally move the mouse too
far and the whole menu closes. That's the scenario (typically found on
CSS-only menus) I want to avoid, so I'd like a "grace period" if you
will.

I didn't mean the delay made no sense, but the usual rollover-only
functionality of canned menu scripts.
If so, then a commercial solution would seem to make sense. Do you
know of good commercial menus?




If I was only looking for that, I'd just write it myself, but I'm not
big on reinventing wheels.

If you aren't looking for what I described, then what are you looking
for?
 
B

Brian Adkins

How so? Your app must not break down when either or both is disabled.

"Must not" ? I'm surprised you think you know enough about the
requirements for my application to be able to make this statement. The
title of this post has to do with recommending JavaScript menus. If
you're not going to make a recommendation, please don't also make such
ridiculous statements. Combining arrogance and ignorance is
inadvisable.

Before you reply with some ridiculous retort, please identify at least
3 major web applications that would practically fall apart if users
disabled both JavaScript & CSS and reconcile that with your statement
above.
I didn't mean the delay made no sense, but the usual rollover-only
functionality of canned menu scripts.

I can see you have many opinions. It's a pity none of them have to do
with the original request.
 
D

David Mark

"Must not" ? I'm surprised you think you know enough about the
requirements for my application to be able to make this statement. The

It has nothing to do with the requirements of your application.
That's a general rule for any competent Web page or application.
title of this post has to do with recommending JavaScript menus. If
you're not going to make a recommendation, please don't also make such
ridiculous statements. Combining arrogance and ignorance is
inadvisable.

The specific response was to your assertion that JS and CSS are
somehow intertwined. It should be intuitively obvious that if you
disable one but not the other, then any reliance on JS to prop up CSS
will be exposed. It is inadvisable to argue a point that you clearly
don't understand.
Before you reply with some ridiculous retort, please identify at least
3 major web applications that would practically fall apart if users
disabled both JavaScript & CSS and reconcile that with your statement
above.

As I suspected, you didn't get the point at all. Regardless, most Web
applications (and many simple Web pages) fall apart when both JS and
CSS are disabled. Name three "major Web applications" that don't.
I can see you have many opinions. It's a pity none of them have to do
with the original request.

The original request matters little at this point. As I mentioned a
few posts back, I have no recommendation for you, other than a few
general rules to follow when evaluating canned menu scripts.
 
T

Thomas 'PointedEars' Lahn

Brian said:
I would appreciate recommendations for JavaScript code that implements
drop-down, hierarchical menus. Are there high quality libraries for
this, or is it more typical for people to roll their own?

Let JScript(!) code add to the functionality of CSS where required. Don't
attempt to replace HTML and the latter by a client-side script that
generates the content; the result would be inevitably inaccessible.


PointedEars
 
P

Peter Michaux

It has nothing to do with the requirements of your application.
That's a general rule for any competent Web page or application.

It does have to do with the specific requirements. Not all web pages
are for general web consumption. Some are for back-end pages where the
user logs in and is known to have a certain set of prerequisite
capabilities. In these cases, spending the extra time to make the page
degrade gracefully or otherwise may not be considered a wise use of
development dollars.

Another option is a gateway page that branches to two versions of the
application. This is like GMail. One branch is for JavaScript enabled
(and sufficiently capable JavaScript) and the other branch is for
anyone not capable of the "full" version. So in this case the fancy
drop down menus would not have to degrade either.

Peter
 
B

Brian Adkins

Here are a few I've found. Any good/bad experiences with any of them?

Yahoo! UI Library: Menu
http://developer.yahoo.com/yui/menu/

Son of Suckerfish - Nice, but menu collapses unforgivingly
http://www.htmldog.com/articles/suckerfish/dropdowns/

FreeStyle Menu - Angus Turnbull
http://www.twinhelix.com/dhtml/fsmenu/demo/

jdMenu plugin for JQuery
http://jdsharp.us/jQuery/plugins/jdMenu/

I also forgot to list one requirement. I'm using XHTML 1.0 Strict, so
the menu would need to be compatible with that.

At this point, I'm leaning toward starting with Son of Suckerfish and
adding JavaScript to make the collapsing more forgiving. It seems like
the simplest and I like the idea of building something onto a simple
foundation versus trying to understand someone else's monstrosity.

I would be curious about experiences with Yahoo's menu or other
libraries with significant developer acceptance.
 
B

Brian Adkins

Brian Adkins said the following on 9/29/2007 12:51 PM:

Why are you using something that isn't understood by 90% of the web and
would end up being processed as soup tag HTML and thus a true XHTML
script wouldn't work with it?

I wasn't aware that "90% of the web" doesn't understand it. Can you
provide documentation for that statistic? I have to admit being
skeptical since my testing has uncovered no issues and there are a
number of major sites using the same doctype, but I'd like to keep an
open mind.

I'm not familiar with the phrase "soup tag HTML", but it doesn't sound
good. Which browsers process XHTML as "soup tag HTML" ? I also don't
know what you mean by a "true XHTML script" - is this different than a
regular old JavaScript script? Are you saying that many browsers will
populate the DOM differently from XHTML input than from HTML? If you
can provide examples of input that validates against XHTML 1.0 Strict
that turns into "soup tag HTML" and thus won't work with a valid
JavaScript program I would appreciate it.

Just out of curiosity, which doctype do you prefer?
 
B

Brian Adkins

I wasn't aware that "90% of the web" doesn't understand it. Can you
provide documentation for that statistic? I have to admit being
skeptical since my testing has uncovered no issues and there are a
number of major sites using the same doctype, but I'd like to keep an
open mind.

I'm not familiar with the phrase "soup tag HTML", but it doesn't sound
good. Which browsers process XHTML as "soup tag HTML" ? I also don't
know what you mean by a "true XHTML script" - is this different than a
regular old JavaScript script? Are you saying that many browsers will
populate the DOM differently from XHTML input than from HTML? If you
can provide examples of input that validates against XHTML 1.0 Strict
that turns into "soup tag HTML" and thus won't work with a valid
JavaScript program I would appreciate it.

Just out of curiosity, which doctype do you prefer?

Just in case we're talking about two different things, here's the
doctype & other stuff I'm using:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
...
<meta http-equiv="Content-Type" content="text/html;
charset=utf-8" />
...
 
T

Thomas 'PointedEars' Lahn

Brian said:
I wasn't aware that "90% of the web" doesn't understand it. Can you
provide documentation for that statistic?

He is referring to Microsoft Internet Explorer not using a built-in XML
parser for XHTML by default, and not supporting the proper media type for
XHTML, application/xhtml+xml, to date (version 7.0). Whether or not it
still has a 90% market share or not (142% of all Web statistics are flawed)
is irrelevant; it is a sad fact that its flawed layout engine (Trident) is
still the most used one, and that the advantages XHTML undoubtedly has over
HTML must still be carefully weighted against the disadvantage of the
former's being not widely supported.

http://en.wikipedia.org/wiki/Internet_Explorer
http://en.wikipedia.org/wiki/Internet_Explorer#Standards_support


PointedEars
 
T

Thomas 'PointedEars' Lahn

Brian said:
Brian Adkins said the following on 9/29/2007 12:51 PM:
[...]
I'm not familiar with the phrase "soup tag HTML", but it doesn't sound
good. Which browsers process XHTML as "soup tag HTML" ?

The correct term is "tag soup HTML" which is the way most (if not all)
parsers in browsers work. If they do no support a HTML feature or encounter
not Valid code, they do error correction. That is a behavior not allowed
for XML documents such as XHTML documents; they have to be well-formed (they
need not to be Valid, although due to the definition of validating parsers
that is strongly recommended).

http://www.hixie.ch/advocacy/xhtml
http://hsivonen.iki.fi/xhtml-the-point/

Did you even know that there is no such thing as a "regular old JavaScript
script" as every different UA uses a different script engine and DOM?

Yes, they do. Although that is not supported by Web standards. For
example, document.write() doesn't work (i.e. throws an exception) in the
XHTML Gecko DOM with the excuse of its being capable of creating not
well-formed markup.

http://www.w3.org/TR/DOM-Level-2-HTML/

HTML 4.01 Strict, unless XHTML is absolutely required. If the latter, XHTML
1.0 Strict or XHTML 1.1.
Just in case we're talking about two different things, here's the
doctype & other stuff I'm using:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
...
<meta http-equiv="Content-Type" content="text/html;
charset=utf-8" />

This is strongly recommended against if you serve it as text/html:

http://www.w3.org/TR/xhtml-media-types/#summary

And, in fact, if the XHTML was parsed by an XML parser as it should be, that
declaration would be far too late. An XML document has to be well-formed
*before* parsing starts. That is facilitated by declaring the encoding in
the HTTP header or in an XML processing instruction before the root element
of the document (PI):

<?xml version="1.0" encoding="ISO-8859-1"?>

As for scripting, there are more things to care about when using XHTML.

http://www.w3.org/TR/xhtml1/#diffs


PointedEars
 
B

Brian Adkins

He is referring to Microsoft Internet Explorer not using a built-in XML
parser for XHTML by default, and not supporting the proper media type for
XHTML, application/xhtml+xml, ...

I see. I'm not serving it as 'application/xhtml+xml', and haven't had
any issues with IE so far. I guess the 'text/html' vs. 'application/
xhtml+xml' accounts for the discrepancy between "90% of the web
doesn't understand it" and what I'm seeing.
 
T

Thomas 'PointedEars' Lahn

Brian said:
I see. I'm not serving it as 'application/xhtml+xml',

But as what?
and haven't had any issues with IE so far. I guess the 'text/html' vs.
'application/xhtml+xml' accounts for the discrepancy between "90% of
the web doesn't understand it" and what I'm seeing.

It merely accounts for the possibility of your not understanding
what you are doing, see <[email protected]>.


PointedEars
 
P

Peter Michaux

I wasn't aware that "90% of the web" doesn't understand it. Can you
provide documentation for that statistic? I have to admit being
skeptical since my testing has uncovered no issues and there are a
number of major sites using the same doctype, but I'd like to keep an
open mind.

I'm not familiar with the phrase "soup tag HTML", but it doesn't sound
good. Which browsers process XHTML as "soup tag HTML" ? I also don't
know what you mean by a "true XHTML script" - is this different than a
regular old JavaScript script? Are you saying that many browsers will
populate the DOM differently from XHTML input than from HTML? If you
can provide examples of input that validates against XHTML 1.0 Strict
that turns into "soup tag HTML" and thus won't work with a valid
JavaScript program I would appreciate it.
See

http://www.thewebcreator.net/2007/04/16/why-you-should-be-using-html-401-instead-of-xhtml/

http://www.webdevout.net/articles/beware-of-xhtml

Just out of curiosity, which doctype do you prefer?

HTML Transitional is the most useful to me because of iframe hacks
(hidden file upload, iframe shim for IE select element hiding).

Peter
 
B

Brian Adkins

Brian said:
Brian Adkins said the following on 9/29/2007 12:51 PM:
[...]
I'm not familiar with the phrase "soup tag HTML", but it doesn't sound
good. Which browsers process XHTML as "soup tag HTML" ?

The correct term is "tag soup HTML" which is the way most (if not all)
parsers in browsers work. If they do no support a HTML feature or encounter
not Valid code, they do error correction. That is a behavior not allowed
for XML documents such as XHTML documents; they have to be well-formed (they
need not to be Valid, although due to the definition of validating parsers
that is strongly recommended).

http://www.hixie.ch/advocacy/xhtml

Interesting information. I do validate my pages, and I'm not planning
on sending as 'application/xhtml+xml' anytime soon, but it certainly
may be that I assumed there were advantages to XHMTL 1.0 Strict after
reading various information sources (i.e. jumped on a bandwagon). Some
of the proposed benefits of XHTML I've heard are:

* future proofing web pages
* allowing aural screen readers to more easily consume it
* it's becoming the language of choice for mobile devices
* existing data is more easily transformed into XHTML than HTML
* there's not going to be an HTML 5, the new standard is XHTML 1.0
* <br> seems wrong compared to <br />
* etc.

For what it's worth, here are the doctypes of 49 sites that I checked
in mid July:

http://lojic.com/blog/2007/07/12/which-doctypes-are-being-used/

Summary is: none = 10, html = 20, xhtml = 19 (only 1 using XHTML 1.1)

You've given me some things to think about. If anyone is aware of
advantages of XHTML 1.1 Strict over HTML 4.01 Strict, feel free to
chime in.
 
B

Brian Adkins

But as what?


It merely accounts for the possibility of your not understanding
what you are doing, see <[email protected]>.

You could be right. I should probably hear your perspective on the
discrepancy between someone's statement that XHTML 1.0 Strict won't
work on "90% of the web", and the fact that I haven't uncovered any
problems (except for losing the target attribute on <a>) on 5 browsers
running on 3 operating systems covering well over 90% market share.

I've heard someone say that the difference between theory and practice
is much greater in practice than in theory ;)
 
D

David Mark

It does have to do with the specific requirements. Not all web pages
are for general web consumption. Some are for back-end pages where the
user logs in and is known to have a certain set of prerequisite
capabilities. In these cases, spending the extra time to make the page
degrade gracefully or otherwise may not be considered a wise use of
development dollars.

Correct, but popup menus are simple enough that you would just do them
right in the first place.
Another option is a gateway page that branches to two versions of the
application. This is like GMail. One branch is for JavaScript enabled

Please don't use Google as an example. Google throws JS errors at me
constantly. But I get the idea. I don't like it, but I get it.
(and sufficiently capable JavaScript) and the other branch is for
anyone not capable of the "full" version. So in this case the fancy
drop down menus would not have to degrade either.

Fancy dropdown menus? Granted they aren't really necessary for most
Web pages/applications, but they are fairly trivial widgets, which is
one reason they are so prevalent.

Hierarchies of menus would seem an unwieldy choice for site
navigation, but it is apparently the preferred UI for most Web
developers. Unfortunately, most implementations have lousy usability
and/or accessibility. It's as if the developers had never used menus
in software applications. Of course, if they were paying attention to
their desktops, they would have noticed that navigation is done with a
tree, not a series of cascading menus.

Here is an example of how I think menus should work. The code is a
little slapdash, but in my brief testing it functioned flawlessly.
The default behavior does not popup top-level menus on rollovers (I
hate that), but there is a global option to change this. And they
don't vanish just because you move the mouse away (click to hide all
active menus.) And yes, there is a configurable delay for hiding sub-
menus when it makes sense to hide them. As for accessibility,
keyboard users will have no problem and I think most screen readers/
aural browsers will work as well. I tested in IE7, the latest Mozilla
and Netscape, Opera 9 and Windows Safari beta. IE7 in quirks mode had
a weird issue with adding space between listitems when sub-menus open,
but I haven't investigated that (you shouldn't use quirks mode
anyway.) It should be okay in IE6 in standards mode.

The example has three menus with identical content: one styled as a
horizontal menubar, one vertical and the other as a popup menu. The
orientations are determined solely by CSS. The instantiation of the
popup menu and positioning of child popups are functions of the
script.

Use something like this and you won't need a branch page as the menus
degrade gracefully without script as well as without script and
style. As usual, the hardest case to get perfect is where script is
enabled but style is not. The specific examples I used are admittedly
lousy in this case as only the leaf nodes navigate, despite the fact
that all nodes have perfectly good href's. So if you must use
cascading menus for navigation (as opposed to commands), it is a good
idea to relegate links to leaf nodes.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/
TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Menus</title>
<style type="text/css" media="all">
ul.menubar { list-style-type:none;padding:0;margin:0 }
ul.menubar a, ul.menuPopup a { padding: 0 .25em 0 .25em }
ul.menubar li { margin:0;padding:0;display:inline}
ul.menubar li a:link, ul.menubar li a:visited { text-decoration:none }
ul.menubar li a:hover { background-color:#0000DD;color:white }
ul.menuPopup { list-style-type:none;padding:0;margin:0;border:eek:utset
2px;background-color:threedface;color:windowtext;z-index:1 }
ul.menuPopup li { white-space:nowrap;display:block }
ul.menuPopup li a:link, ul.menuPopup li a:visited { text-
decoration:none;display:block }
ul.menuPopup li a:hover { background-
color:#0000DD;color:white;display:block }
ul.menuPopup li a.popup:after { content: "\0020\00BB"; }

#myMenubarVertical.menubar { width:5em;margin-bottom:1em }
#myMenubarVertical.menubar li, #myMenubarVertical.menubar li a
{ display:block }
#testPopupMenu { display:block; margin-top:1em }

body {font-family:sans-serif;background-color:threedface}
</style>
<!--[if IE]>
<style type="text/css" media="all">
ul.menubar { display:inline-block } /* Adds layout to fix IE relative
positioning bug
</style>
<![endif]-->
<style type="text/css" media="handheld">
body { margin:4px }
</style>
<style type="text/css" media="print">
body {font-family:serif}
ul.menubar, ul.menuPopup { list-style-type:disc;padding:0 0 0 1em }
ul.menuPopup { border:none;background-
color:white;color:black;position:static !important;display:block !
important }
ul.menuPopup li a {color:black;background-color:inherit}
ul.menuPopup li a.popup:after { content: ""; }
#testPopupMenu { display:none }
</style>
<script type="text/javascript">
var global = this;
if (this.document && this.document.getElementsByTagName &&
this.document.getElementById) {
(function() {
var html = global.document.getElementsByTagName('html');
if (html && html[0] && html[0].style &&
typeof(html[0].style.visibility) == 'string')
{ global.document.write('<style type="text/css"
media="all">#myMenubar, #myMenubarVertical, #myPopupMenu,
#testPopupMenu { visibility:hidden }<\/style>'); }
})();

this.onload = function() {
// Global options
var menuPause = 500; // Delay before hiding/showing sub-menu
var startWithRollover = false; // Default requires click to show
initial top-level item (second click hides)
// Set to true to allow rollover to show top-level menus (click
navigates)

var doc = global.document;
var el, elButton;

var activeMenu, timer, hrefTypeUnknown;

function nodeName(el) {
var n = (el.tagName || el.nodeName);
return n && n.toLowerCase();
}

function cancelPropagation(e) {
e = e || global.event;
if (e.stopPropagation) { e.stopPropagation(); }
e.cancelBubble = true;
}

function setStatus(s) {
// Firefox unload/mouseover bug requires typeof check here
if (typeof(global) != 'undefined') { global.setTimeout(function()
{ if (typeof(global) != 'undefined') { global.status = s; } }, 0); }
return true;
}

function menuRoot(list) {
var root;

if (!list.parentNode || nodeName(list.parentNode) != 'li') { return
null; }
while (list.parentNode) {
list = list.parentNode;
if (list && nodeName(list) == 'ul') { root = list; }
}
return (root._isRootless)?null:root;
}

function isAncestor(listChild, listParent) {
while (listChild.parentNode && listChild.parentNode != document) {
if (listChild.parentNode == listParent) { return true; }
listChild = listChild.parentNode;
}
}

function hideActiveMenu(branch, root) {
if (timer) { global.clearTimeout(timer); timer = null; }
activeMenu.style.display = 'none';
var parentMenuItem = activeMenu.parentNode;
if (parentMenuItem && nodeName(parentMenuItem) == 'li' &&
parentMenuItem.parentNode && parentMenuItem.parentNode != branch &&
parentMenuItem.parentNode != root) {
activeMenu = parentMenuItem.parentNode;
hideActiveMenu(branch, root);
}
activeMenu = branch || null;
}

function showMenu(el, branch, side, pos) {
if (timer) { global.clearTimeout(timer); timer = null; }
var elOffset, elParent, tag, a;

side = side || 'bottom';
elParent = el.parentNode;

el.style.visibility = 'hidden';
el.style.display = 'block';

if (!pos && elParent && nodeName(elParent) == 'li') {
pos = [0, 0];
if (elParent != branch) {
elOffset = elParent;
do {
pos[0] += elOffset.offsetTop || 0;
pos[1] += elOffset.offsetLeft || 0;
if (elParent != elOffset) {
pos[0] += elOffset.clientTop || 0;
pos[1] += elOffset.clientLeft || 0;
}
elOffset = elOffset.offsetParent;
if (elOffset) {
tag = nodeName(elOffset);
if (tag != 'li' && tag != 'ul') { break; }
}
}
while (elOffset && elOffset != branch);
}
if (side == 'right') { pos[1] += elParent.offsetWidth || 0; } else
{ pos[0] += elParent.offsetHeight || 0; }
}
if (pos) {
el.style.top = pos[0] + 'px';
el.style.left = pos[1] + 'px';
}
el.style.visibility = 'visible';

if (activeMenu && !isAncestor(el, activeMenu) && activeMenu != el)
{
var root = menuRoot(activeMenu);
hideActiveMenu((branch == root)?null:branch, root);
}

activeMenu = el;

a = el.getElementsByTagName('a');
if (a[0] && a[0].focus) { a[0].focus(); }
}

function showMenuPopup(el) {
showMenu(el, null);
}

function attachPopupActivator(el, list) {
el.onclick = function(e) { if (list.style.display == 'none')
{ showMenu(list, null); } else { hideActiveMenu(null, null); }
cancelPropagation(e); };
}

function initializeChildMenus(list, root, initialSide) {
initialSide = initialSide || 'bottom';
if (typeof(root) == 'undefined') { root = list; }
var lists, itemFocused;
var anchors = list.getElementsByTagName('a');
var i = 0;
var l = anchors.length;
while (i < l) {
if (anchors.parentNode) {
lists = anchors.parentNode.getElementsByTagName('ul');
if (lists && lists[0]) {
if (lists[0].style.display != 'none') { // already did this one?
hrefTypeUnknown = typeof(anchors.href) == 'unknown';
if (root != list || !startWithRollover || (!hrefTypeUnknown && !
anchors.href)) {
if (!hrefTypeUnknown) { anchors.href = anchors.href ||
'#'; }
anchors.onclick = (function(el) { return function(e) { if
(el.style.display == 'none') { showMenu(el, list, (root == list)?
initialSide:'right'); } else { if (root == list)
{ hideActiveMenu((root == list)?null:list, root); } }
cancelPropagation(e); return false; }; })(lists[0]);

}
anchors.tabIndex = 0;
initializeChildMenus(lists[0], root);
anchors.onmouseover = (function(el) { return function(e)
{ if (this.title) { setStatus(this.title); } if ((!activeMenu && !
startWithRollover) || (activeMenu && isAncestor(activeMenu, el)))
{ return; } if (timer) { global.clearTimeout(timer); } timer =
global.setTimeout(function() { showMenu(el, list, (root == list)?
initialSide:'right'); }, (list == root)?0:menuPause); return
true; }; })(lists[0]);
anchors.onmouseout = function() { if (timer)
{ clearTimeout(timer); timer = null; } if (this.title) { return
setStatus(''); } };
anchors.className = 'popup';
lists[0].className = 'menuPopup';
lists[0].style.position = 'absolute';
lists[0].style.display = 'none';
}
}
else {
if (anchors.parentNode.parentNode &&
anchors.parentNode.parentNode.style.display != 'none') { // already
did this one?
anchors.onmouseover = function() { if (this.title)
{ setStatus(this.title); } if (timer) { global.clearTimeout(timer);
timer = 0; } if (activeMenu && !isAncestor(this, activeMenu)) { timer
= global.setTimeout(function() { hideActiveMenu((list == root)?
null:list, menuRoot(activeMenu)); }, (list == root)?0:menuPause); }
return true; };
anchors.onmouseout = function() { if (this.title) { return
setStatus(''); } };
}
}
i++;
}
}
if (l) {
global.onunload = function() {
i = 0;
l = anchors.length;
while(i < l) {
anchors.onclick = anchors.onmouseover =
anchors.onmouseout = null;
i++;
}
};
}
}

function documentClickHandler(list, root) {
if (typeof(root) == 'undefined') { root = list; }
return function() {
if (activeMenu && (isAncestor(activeMenu, list) || activeMenu ==
list)) { hideActiveMenu(null, root); }
};
}

function attachDocumentClickHandler(list, root) {
var onclickOld = document.onclick;
var onclickNew = documentClickHandler(list, root);
document.onclick = (onclickOld)?function(e) { onclickOld(e);
onclickNew(e); }:eek:nclickNew;
}

function initializeMenu(list, className, initialSide) {
list.className = className || 'menubar';
list.style.position = 'relative';
initializeChildMenus(list, list, initialSide);
attachDocumentClickHandler(list);
}

function initializeMenuPopup(list, className) {
list.className = className || 'menuPopup';
list._isRootless = true;
initializeChildMenus(list, null);
list.style.position = 'absolute';
list.style.display = 'none';
attachDocumentClickHandler(list, null);
}

el = doc.getElementById('myMenubar');
if (el && el.parentNode && el.style && typeof(el.style.display) ==
'string' && typeof(el.style.position) == 'string') {
initializeMenu(el);
el.style.visibility = 'visible';
el = doc.getElementById('myMenubarVertical');
if (el) {
initializeMenu(el, null, 'right');
el.style.visibility = 'visible';
}
el = doc.getElementById('myPopupMenu');
if (el) {
initializeMenuPopup(el);
el.style.visibility = 'visible';
elButton = document.getElementById('testPopupMenu');
if (elButton) {
elButton.disabled = false;
attachPopupActivator(elButton, el);
elButton.style.visibility = 'visible';
}
}
}

};
}
</script>
</head>
<body>
<ul id="myMenubarVertical"><li><a title="Google sites" href="http://
www.google.com">Google</a><ul><li><a href="http://
www.gmail.com">GMail</a><ul><li><a href="http://www.gmail.com">Inbox</
a></li><li><a href="http://www.gmail.com">Outbox</a></li></ul></
li><li><a href="http://www.googlecode.com">Google Code</a><ul><li><a
href="http://code.google.com/apis/ajaxsearch/">Google Ajax Search</a></
li><li><a href="http://www.google.com/apis/maps/">Google Maps</a></
li><li><a href="http://code.google.com/webtoolkit/">Google Web
Toolkit</a></li></ul></li><li><a href="http://www.google.com/
talk">GTalk</a></li></ul></li><li><a href="http://www.msn.com"
title="MSN sites">MSN</a><ul><li><a href="http://www.msnbc.com">News</
a></li><li><a href="http://msn.foxsports.com">Sports</a></li><li><a
href="http://weather.msn.com">Weather</a></li></ul></li><li><a
href="http://www.yahoo.com" title="Yahoo! site">Yahoo!</a><ul><li><a
href="http://www.yahoo.com/r/26">Sports</a></li><li><a href="http://
www.yahoo.com/r/4c">Tech</a></li></ul></li></ul>
<ul id="myMenubar"><li><a title="Google sites" href="http://
www.google.com">Google</a><ul><li><a href="http://
www.gmail.com">GMail</a><ul><li><a href="http://www.gmail.com">Inbox</
a></li><li><a href="http://www.gmail.com">Outbox</a></li></ul></
li><li><a href="http://www.googlecode.com">Google Code</a><ul><li><a
href="http://code.google.com/apis/ajaxsearch/">Google Ajax Search</a></
li><li><a href="http://www.google.com/apis/maps/">Google Maps</a></
li><li><a href="http://code.google.com/webtoolkit/">Google Web
Toolkit</a></li></ul></li><li><a href="http://www.google.com/
talk">GTalk</a></li></ul></li><li><a href="http://www.msn.com"
title="MSN sites">MSN</a><ul><li><a href="http://www.msnbc.com">News</
a></li><li><a href="http://msn.foxsports.com">Sports</a></li><li><a
href="http://weather.msn.com">Weather</a></li></ul></li><li><a
href="http://www.yahoo.com" title="Yahoo! site">Yahoo!</a><ul><li><a
href="http://www.yahoo.com/r/26">Sports</a></li><li><a href="http://
www.yahoo.com/r/4c">Tech</a></li></ul></li></ul>
<input type="button" id="testPopupMenu" value="Popup menu" disabled>
<ul id="myPopupMenu"><li><a title="Google sites" href="http://
www.google.com">Google</a><ul><li><a href="http://
www.gmail.com">GMail</a><ul><li><a href="http://www.gmail.com">Inbox</
a></li><li><a href="http://www.gmail.com">Outbox</a></li></ul></
li><li><a href="http://www.googlecode.com">Google Code</a><ul><li><a
href="http://code.google.com/apis/ajaxsearch/">Google Ajax Search</a></
li><li><a href="http://www.google.com/apis/maps/">Google Maps</a></
li><li><a href="http://code.google.com/webtoolkit/">Google Web
Toolkit</a></li></ul></li><li><a href="http://www.google.com/
talk">GTalk</a></li></ul></li><li><a href="http://www.msn.com"
title="MSN sites">MSN</a><ul><li><a href="http://www.msnbc.com">News</
a></li><li><a href="http://msn.foxsports.com">Sports</a></li><li><a
href="http://weather.msn.com">Weather</a></li></ul></li><li><a
href="http://www.yahoo.com" title="Yahoo! site">Yahoo!</a><ul><li><a
href="http://www.yahoo.com/r/26">Sports</a></li><li><a href="http://
www.yahoo.com/r/4c">Tech</a></li></ul></li></ul>
</body>
</html>
 
B

Brian Adkins

But please do that only where it is on-topic.

That is appropriate, but I find it humorous nonetheless considering
very little of this thread has been on topic. Who knows, maybe someone
will show up with some useful info regarding JavaScript menus after
all.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,479
Members
44,899
Latest member
RodneyMcAu

Latest Threads

Top