I've moved my work to a dedicated standalone file. The progress in the code below is considerable though not acceptable just yet.
Some details...
1.) All browsers are keyboard accessible, press/hold down the Tab key on the keyboard.
2.) Clicking on the body (white bordered divisible element) will hide the menus (I hate sites where the menus just won't go the f$%^ away!)
3.) Holding Shift+Tab will for the most part hide the next menu (when you are keyboard navigating backwards) with some exceptions such as IE6.
4.) The styling is mostly complete though there some minor bugs here and there mostly in IE6.
Functionality wise it's I'd say 95% complete. I have not added support for third level menus and frankly I'm getting so tired of working on this because more then half the work has been fixing IE that if I add it then it'll likely be at a later date.
I've tested this in...
Firefox 3.0
Opera 10
Safari
XP IE6 (system non-standalone, in VirtualBox)
XP IE7 (system non-standalone, in Virtual PC)
XP IE8 (system non-standalone, my base XP install)
Code: Select all
<?php echo '<?xml version="1.0" encoding="UTF-8"?>'."\n";?>
<!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" xml:lang="en">
<head>
<title>IE6 Suckerfish Menu</title>
<script type="text/javascript">
//<![CDATA[
function change(id, newClass) {var identity=document.getElementById(id); identity.className=newClass;}
function menu()
{
/* IE7 Bug fix; IE7 ignores case for getElementById, IE8 does not, do NOT change casing! */
if (document.getElementById('Body') && window.XMLHttpRequest) {if (document.getElementById('body').currentStyle.backgroundColor=='transparent') {document.getElementById('body').style.backgroundColor=document.body.currentStyle.backgroundColor;}}
/* Add #body onclick event to hide all menus. */
if (window.addEventListener) {document.getElementById('body').addEventListener('click', function() {menu_hide();},false);}
else {document.getElementById('body').attachEvent('onclick', function() {menu_hide();});}
var menus = document.getElementById('menu').childNodes.length;
for (var i=1;i<=menus;i++)
{
var a = 'm'+i;
var b = 'm'+i+'b';
if (document.getElementById(a))
{
var c = document.getElementById(a).childNodes[0];
menu_event(a,b,c,i);
}
}
}
function menu_event(a,b,c,i)
{
if (window.addEventListener)
{
c.addEventListener('focus', function() {change(b,'menu_bh'); menu_hide_shift_tab(i);},false);
c.addEventListener('blur', function() {c.className='menu_h';},false);
var l = document.getElementById(b).childNodes.length-2;
document.getElementById(b).childNodes[l].lastChild.addEventListener('blur', function() {change(b,'submenu'); c.className='menu';},false);
}
else if (window.XMLHttpRequest)
{
c.attachEvent('onfocus', function() {change(b,'menu_bh'); menu_hide_shift_tab(i);});
c.attachEvent('onblur', function() {c.className='menu_h';});
var l = document.getElementById(b).childNodes.length-1;
document.getElementById(b).childNodes[l].lastChild.attachEvent('onblur', function() {change(b,'submenu'); c.className='menu';});
}
else
{
document.getElementById(a).attachEvent('onmouseover', function() {change(a,'menu_ah'); change(b, 'menu_bh'); c.className='menu_h';});
document.getElementById(a).attachEvent('onmouseout', function() {change(a,'menu');});
c.attachEvent('onfocus', function() {change(a,'menu_ah'); change(b, 'menu_bh'); c.className='menu_a';});
c.attachEvent('onblur', function() {c.className='menu_a'});
document.getElementById(b).lastChild.lastChild.attachEvent('onblur', function() {document.getElementById(a).className='menu'; c.className='menu';});
}
}
function menu_hide_shift_tab(d)
{
if (d)
{
//alert(d);
var i = d+1;
var a = 'm'+i;
var b = 'm'+i+'b';
if (document.getElementById(a))
{
var c = document.getElementById(a).childNodes[0];
change(b,'submenu');
c.className='menu';
}
}
}
function menu_hide()
{
var menus = document.getElementById('menu').childNodes.length;
for (var i=1;i<=menus;i++)
{
var a = 'm'+i;
var b = 'm'+i+'b';
menu_hide2(a,b);
}
}
function menu_hide2(a,b)
{
if (document.getElementById(a))
{
var c = document.getElementById(a).childNodes[0];
if (window.addEventListener)
{
change(b,'submenu');
c.className='menu';
}
else if (document.getElementById(b))
{
//var l = document.getElementById(b).childNodes.length-2;
//change(b,'submenu');
document.getElementById(a).className='menu';
document.getElementById(b).className='submenu';
}
}
}
window.onload = function()
{
if (!document.all)
{
menu();
}
else
{
if (!window.XMLHttpRequest) {ie56_body();}
menu();
//ie_menu_1();
}
};
//]]>
</script>
<style type="text/css">
a:link {color: #6c6; font-size: 17px; text-decoration: none;}
a:visited {color: #6c6; font-size: 17px; text-decoration: none;}
a:focus, a:hover {background-color: #666; color: #fff; text-decoration: underline;}
a:active {color: #cfc; text-decoration: none;}
body, html {background-color: #000; color: #f0f; overflow: hidden;}
#body {border: #fff solid; border-width: 40px 1px 1px 1px; bottom: 36px; left: 4px; position: absolute; overflow: auto; right: 4px; top: 9px; z-index: 1;}
#head {background-color: #222; height: 39px; left: 5px; position: absolute; right: 5px; top: 10px; z-index: 2;}
#head #menu {height: 20px; left: 0px; position: absolute; top: 19px; z-index: 3;}
#head #menu div.menu {float: left; font-size: 16px; height: 20px; overflow: hidden; text-align: center; width: 84px;}
#head #menu a.menu:link, #head #menu a.menu:visited {background-color: #222; background-image: url(themes/classic/interface-menu-down.gif); background-position: 69px 11px; background-repeat: no-repeat; border: #666 solid; border-width: 1px 1px 0px 1px; display: block; font-size: 17px; height: 18px; line-height: 16px; margin: 1px 1px 0px 1px;}
#head #menu a.menu:hover, #head #menu a.menu:focus, #head #menu a.menu:active, #head #menu a.menu_a:link, #head #menu a.menu_a:visited {background-color: #696; background-position: 70px 12px; border-color: #ccc #999 transparent #ccc; border-style: solid; border-width: 1px 1px 0px 1px; font-size: 17px; height: 19px; margin: 0px; padding-top: 1px; vertical-align: top;}
#head #menu a.menu_h:link, #head #menu a.menu_h:visited, #head #menu div.menu:hover a.menu {background-color: #69d; background-image: url(themes/classic/interface-menu-down.gif); background-position: 69px 11px; background-repeat: no-repeat; border: #666 solid; border-width: 1px 1px 0px 1px; color: #fff; display: block; font-size: 17px; height: 19px; line-height: 16px; margin: 0px; padding-top: 1px;}
#head #menu div.menu div.submenu {display: none;}
#head #menu div.menu:hover, div.menu_ah {height: 18px; overflow: visible;}
#head #menu div.menu:hover div.submenu, div.menu_bh {background-color: #222; border-color: #ccc #666 transparent #ccc; border-style: solid; border-width: 1px 1px 0px 1px; display: block; position: absolute; top: 20px; width: 160px;}
/*
#head #menu div.menu a.current {background-color: #000; border-color: #ccc #999 transparent #ccc; border-style: solid; border-width: 1px 1px 0px 1px; color: #0c0;}
#head #menu div.menu a.current:focus, #head #menu div.menu a.current:hover {color: #0f0;}
*/
#head #menu a:link, #head #menu a:visited {background-color: #222; border: #666 solid; border-width: 0px 0px 1px 0px; display: block; height: 19px;}
#head #menu a:focus, #head #menu a:hover {background-color: #696; border-bottom-color: #ebef92;}
#head #menu div.menu div.submenu div {border: #666 solid; border-width: 0px 0px 1px 0px; height: 19px;}
#head #menu #m1b {left: 0px;}
#head #menu #m2b {left: 45px;}
#head #menu #m3b {left: 129px;}
#head #menu #m4b {left: 213px;}
#head #menu #m5b {left: 297px;}
#head #menu #m6b {left: 381px;}
#head #menu #m7b {left: 465px;}
#head #menu #m8b {left: 549px;}
#head #menu #m9b {left: 633px;}
</style>
<!--[if IE 6]>
<script type="text/javascript">
//<![CDATA[
function ie56_body()
{
if (top.location.href!= window.location.href)
{
// Frame
change('body', 'body');
change('head', 'head');
document.getElementById('body').style.height = document.body.clientHeight-6;
document.getElementById('body').style.top = 3;
document.getElementById('body').style.width = document.body.clientWidth-8;
document.getElementById('head').style.top = 4;
document.getElementById('head').style.width = document.body.clientWidth-10;
}
else
{
// No Frame
change('body', 'bodyaf');
change('head', 'headaf');
document.getElementById('body').style.height = document.body.clientHeight-44;
document.getElementById('body').style.top = 8;
document.getElementById('body').style.width = document.body.clientWidth-8;
document.getElementById('head').style.top = 9;
document.getElementById('head').style.width = document.body.clientWidth-10;
}
}
/*
function ie_menu_1()
{
var menus = document.getElementById('menu').childNodes.length;
for (var i=1,l=menus.length;i<l;i++)
{
var a1 = 'm' + i;
var b1 = 'm' + i + 'b';
var a = document.getElementById(a1);
var b = document.getElementById(b1);
if (a && b)
{
a.elementIndex = b.elementIndex = i; //Assign that index to elements
a.attachEvent('onmouseover', a_mouseover);
b.firstChild.attachEvent('onfocus', b_focus);
a.attachEvent('onmouseout', a_mouseout);
b.lastChild.lastChild.attachEvent('onblur', b_blur);
}
else {alert(a+' does not exist?');}
}
}
//If these function will be inside loop (like it was), then there will be created 4 * menu_a.length functions instead of 4 needed.
function a_mouseover () {change('m' + this.elementIndex,'menu_ah'); change('m' + this.elementIndex + 'b', 'menu_bh');}
function a_mouseout () {change('m' + this.elementIndex,'menu');}
function b_focus () {change('m' + this.elementIndex,'menu_ah'); change('m' + this.elementIndex + 'b', 'menu_bh');}
function b_blur () {change('m' + this.elementIndex,'menu');}
*/
function ie_menu_1()
{
var menus = document.getElementById('menu').childNodes.length;
var i=1;
for (l=menus;i<=l;i++)
{
var a = 'm'+i;
var b = 'm'+i+'b';
if (document.getElementById(a) && document.getElementById(b))
{
ie_menu_2(a,b);
}
}
}
function ie_menu_2(a,b)
{
document.getElementById(a).attachEvent('onmouseover', function() {change(a,'menu_ah'); change(b, 'menu_bh');});
document.getElementById(a).childNodes(0).attachEvent('onfocus', function() {change(a,'menu_ah'); change(b, 'menu_bh');});
document.getElementById(a).attachEvent('onmouseout', function() {change(a,'menu');});
document.getElementById(b).lastChild.lastChild.attachEvent('onblur', function() {change(a,'menu');});
}
//]]>
</script>
<style type="text/css">
#head #menu a:link, #head #menu a:visited {line-height: 20px; text-align: center;}
#head #menu div.menu a:link, #head #menu div.menu a:visited {font-size: 17px;}
#head #menu div.menu_ah {float: left; width: 84px;}
</style>
<![endif]-->
</head>
<body>
<div id="body">
<div id="liquid">
<br /><br />
<p onclick="var z = document.getElementById('m1').childNodes[0].className; alert(document.getElementById('m1').className+'\n'+document.getElementById('test').className);">stuff stuff stuff stuff stuff stuff stuff stuff stuff stuff stuff stuff stuff stuff stuff</p>
</div>
</div><!-- /#liquid -->
</div><!-- /#body -->
<div id="head">
<div id="menu">
<div class="menu" id="m1"><a class="menu" href="#" id="test" tabindex="2">Section 1</a>
<div class="submenu" id="m1b">
<div><a href="#" tabindex="2">Sub-Menu 1</a></div>
<div><a href="#" tabindex="2">Sub-Menu 1</a></div>
<div><a href="#" tabindex="2">Sub-Menu 1</a></div>
<div><a href="#" tabindex="2">Sub-Menu 1</a></div>
<div><a href="javascript: alert(document.getElementById('m1b').className);" tabindex="2">Sub-Menu 9</a></div>
</div>
</div>
<div class="menu" id="m2"><a class="menu" href="#" tabindex="2">Section 2</a>
<div class="submenu" id="m2b">
<div><a href="#" tabindex="2">Sub-Menu 2</a></div>
<div><a href="#" tabindex="2">Sub-Menu 2</a></div>
<div><a href="#" tabindex="2">Sub-Menu 2</a></div>
<div><a href="#" tabindex="2">Sub-Menu 2</a></div>
<div><a href="javascript: alert(document.getElementById('m2b').className);" tabindex="2">Sub-Menu 9</a></div>
</div>
</div>
<div class="menu" id="m3"><a class="menu" href="#" tabindex="2">Section 3</a>
<div class="submenu" id="m3b">
<div><a href="#" tabindex="2">Sub-Menu 3</a></div>
<div><a href="#" tabindex="2">Sub-Menu 3</a></div>
<div><a href="#" tabindex="2">Sub-Menu 3</a></div>
<div><a href="#" tabindex="2">Sub-Menu 3</a></div>
</div>
</div>
<div class="menu" id="m4"><a class="menu" href="#" tabindex="2">Section 4</a>
<div class="submenu" id="m4b">
<div><a href="#" tabindex="2">Sub-Menu 4</a></div>
<div><a href="#" tabindex="2">Sub-Menu 4</a></div>
<div><a href="#" tabindex="2">Sub-Menu 4</a></div>
<div><a href="#" tabindex="2">Sub-Menu 4</a></div>
</div>
</div>
<div class="menu" id="m5"><a class="menu" href="#" tabindex="2">Section 5</a>
<div class="submenu" id="m5b">
<div><a href="#" tabindex="2">Sub-Menu 5</a></div>
<div><a href="#" tabindex="2">Sub-Menu 5</a></div>
<div><a href="#" tabindex="2">Sub-Menu 5</a></div>
<div><a href="#" tabindex="2">Sub-Menu 5</a></div>
</div>
</div>
<div class="menu" id="m6"><a class="menu" href="#" tabindex="2">Section 6</a>
<div class="submenu" id="m6b">
<div><a href="#" tabindex="2">Sub-Menu 6</a></div>
<div><a href="#" tabindex="2">Sub-Menu 6</a></div>
<div><a href="#" tabindex="2">Sub-Menu 6</a></div>
<div><a href="#" tabindex="2">Sub-Menu 6</a></div>
</div>
</div>
<div class="menu" id="m7"><a class="menu" href="#" tabindex="2">Section 7</a>
<div class="submenu" id="m7b">
<div><a href="#" tabindex="2">Sub-Menu 7</a></div>
<div><a href="#" tabindex="2">Sub-Menu 7</a></div>
<div><a href="#" tabindex="2">Sub-Menu 7</a></div>
<div><a href="#" tabindex="2">Sub-Menu 7</a></div>
</div>
</div>
<div class="menu" id="m8"><a class="menu" href="#" tabindex="2">Section 8</a>
<div class="submenu" id="m8b">
<div><a href="#" tabindex="2">Sub-Menu 8</a></div>
<div><a href="#" tabindex="2">Sub-Menu 8</a></div>
<div><a href="#" tabindex="2">Sub-Menu 8</a></div>
<div><a href="#" tabindex="2">Sub-Menu 8</a></div>
</div>
</div>
<div class="menu" id="m9"><a class="menu" href="#" tabindex="2">Section 9</a>
<div class="submenu" id="m9b">
<div><a href="#" tabindex="2">Sub-Menu 9</a></div>
<div><a href="#" tabindex="2">Sub-Menu 9</a></div>
<div><a href="#" tabindex="2">Sub-Menu 9</a></div>
</div>
</div>
</div><!-- /#menu -->
</div><!-- /#head -->
</body>
</html>