Friendly Mega Drop-down
This is an attempt to create a mega drop-down that is fully compliant with Jakob Nielsen's speed requirements. http://www.useit.com/alertbox/mega-dropdown-menus.html
by morrison
HTML
<header>
<div class='wrapper'>
<p class='hello'>Hello, there.</p>
<h1>Are you looking for a friendly drop-down menu?</h1>
<p>This menu will be fully compliant with <a href='http://www.useit.com/alertbox/mega-dropdown-menus.html'>Jakob Nielsen's guidelines for mega drop-downs</a> when it is completed.</p>
</div>
</header>
<nav id='menu' class='clearfix'>
<ul id="root">
<li>
<a href="#" class="home">Home</a>
</li>
<li class='menu'>
<a href="#" class="products">Products</a>
<section>
<ul>
<li><h2><a href="#">Desktop</a></h2></li>
<li><a href="#">Navigation Link</a></li>
<li><a href="#">Navigation Link</a></li>
<li><a href="#">Navigation Link</a></li>
<li><a href="#">Navigation Link</a></li>
</ul>
<ul>
<li><h2><a href="#">Laptop</a></h2></li>
<li><a href="#">Navigation Link</a></li>
<li><a href="#">Navigation Link</a></li>
<li><a href="#">Navigation Link</a></li>
<li><a href="#">Navigation Link</a></li>
<li><a href="#">Navigation Link</a></li>
<li><a href="#">Navigation Link</a></li>
<li><a href="#">Navigation Link</a></li>
</ul>
<ul>
<li><h2><a href="#">Accessories</a></h2></li>
<li><a href="#">Navigation Link</a></li>
<li><a href="#">Navigation Link</a></li>
<li><a href="#">Navigation Link</a></li>
<li><a href="#">Navigation Link</a></li>
<li><a href="#">Navigation Link</a></li>
<li><a href="#">Navigation Link</a></li>
<li><a href="#">Navigation Link</a></li>
...
CSS
/* Un-related styles */
a {
color:#001948;
}
a:visited {
color:#8255AC;
}
.clearfix:before, .clearfix:after { content: "\0020"; display: block; height: 0; overflow: hidden; }
.clearfix:after { clear: both; }
.clearfix { zoom: 1; }
h1,h2,h3,h4,h5,h6,p {
margin:0;
padding:.5em;
}
html {
overflow-y:scroll;
}
body {
margin: 0 auto; padding: 0;
font: normal 10px Verdana, Arial, Helvetica, sans-serif;
}
* {
outline: none;
}
header {
background:#95B5D7;
}
header .wrapper {
padding:1em 0;
color:#4D6783;
text-shadow:0 .1em .1em rgba(255,255,255,.33);
font-weight:bold;
}
header .wrapper,
ul#root {
margin: 0 auto;
min-width:700px;
width:80%;
}
nav {
background:#2C6BAE;
border-top:1px solid #C3D7EB;
border-bottom:1px solid #fff;
box-shadow:0 5px rgba(0,0,0,.8);
}
section#content {
border-top:1px solid #ddd;
background:#fff;
background:-webkit-gradient(
linear,
left bottom,
left top,
color-stop(1, #eee),
color-stop(0, #fff)
);
background:-moz-linear-gradient(
center top,
#eee,
#fff
);
min-height:400px;
}
/* end Un-related styles */
ul#root {
padding: 0;
list-style: none;
font-size: 1.1em;
}
ul#root li {
float: left;
margin: 0;
padding: 0;
position: relative;
}
ul#root > li.menu > a {
background: url('http://reviews.reviewboard.org/media/rb/images/dropdown.png') no-repeat right;
}
ul#root li:hover {
background-color: #3388bb;
}
ul#root li a {
display:block;
float: left;
padding:1em 2em;
color:#001948;
text-decoration:none;
text-shadow:0 .1em .1em rgba(255,255,255,.33);
font-weight:bold;
}
ul#root li section {
display:none;
position: absolute;
top: 3em;
left: 0;
background: #fff;
padding:2em;
float: left;
/*--Bottom right rounded corner--*/
-moz-border-radius-bottomright: .5em;
...
JavaScript
(function($) {
$.fn.megaDropDown = function(options) {
// Extend our default options with those provided.
// Note that the first arg to extend is an empty object -
// this is to keep from overriding our "defaults" object.
this.opts = $.extend({}, {
'enterDelay': 500,
'leaveDelay': 500,
'transitionTime': 100
}, options);
this.move = {
target: null,
timer: null
};
this.leave = {
target: null,
timer: null
};
this.onMove = function(event) {
if (this.move.timer !== null && event.currentTarget === this.move.target) {
clearTimeout(this.move.timer);
this.move.timer = null;
}
if (this.leave.target === this.move.target) {
clearTimeout(this.leave.timer);
this.leave.timer = null;
this.leave.target = null;
}
this.move.target = event.currentTarget;
this.move.timer = setTimeout(function() {
$(menu.move.target).children('section').slideDown(menu.opts.transitionTime);
}, this.opts.enterDelay);
};
this.onLeave = function(event) {
var target = event.currentTarget;
//if we have a move happening, and leave is the same target, then
//clear the move timer
if (this.move.target !== null && target === this.move.target) {
clearTimeout(this.move.timer);
this.move.timer = null;
this.move.target = null;
}
//if the leave target isn't null and the event target is not the leave target
//then return
if (this.leave.target !== null && target !== this.leave.target) {
return;
}
this.leave.target = event.currentTarget;
this.leave.timer =...