DZone Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

Snippets has posted 5883 posts at DZone. View Full User Profile

Mega Menus With Delay In YUI; Pure Css Fallback

10.30.2009
| 4127 views |
  • submit to reddit
        // description of your code here


mega menus, Brian Tingle, 2009 June

How to do in pure css / hack for IE that uses javascript / ported to YUI below
http://www.htmldog.com/articles/suckerfish/example/

Jakob Nielsen's Alertbox, March 23, 2009 says there should be .5sec delay
http://www.useit.com/alertbox/mega-dropdown-menus.html

This will do what jakob wants; because it checks if the mouse is still moving, but it is jQuery
http://cherne.net/brian/resources/jquery.hoverIntent.html

This is pretty close to what jakob wants...ported to YUI below
How to add delay to :hover onMouseOver/onMouseOut using setTimeout / clearTimeout:
http://forums.devshed.com/javascript-development-115/adding-delay-on-hover-over-for-submenu-on-vertical-navigation-545902.html

How to turn off the pure css menus using javascript to enable delay
http://stackoverflow.com/questions/311052/setting-css-pseudo-class-rules-from-javascript

CSS:
 
 .hidden-menu { display: none; }

 .hover-delay .menu-trigger:hover > .hidden-menu { display: none; }

 .menu-trigger:hover > .hidden-menu,
 .menu-trigger.hover > .hidden-menu,
 .hover-delay .menu-trigger.hover > .hidden-menu
 { display: block; }

 #top-nav #services { height: 100%; }


Javascript:

/* requires http://yui.yahooapis.com/2.7.0/build/yahoo-dom-event/yahoo-dom-event.js 
 The copy of IE on the terminal server does not work with the menu unless this file
 is copied locally
*/

function init() {
	// break pure css version so we can have the delay
	YAHOO.util.Dom.addClass(document.body,'hover-delay')

	// function to show the menu
	// onmouseover with delay
	function showmore() { 
		// work around setTimeout context reset
		var that = this;
		// left hand needs to know what the right hand is up to
		if (this.hideWait) clearTimeout(this.hideWait);
		this.showWait = setTimeout( function() { 
				// add a trigger class
				YAHOO.util.Dom.addClass(that, 'hover');
				// this is supposed to help garbage collection
				that = null;
			}, 100 );
	} 

	// function to hide the menu
	// onmouseout with delay
	function hideagain() { 
		var that = this;
		if (this.showWait) clearTimeout(this.showWait);
		this.hideWait = setTimeout( function() { 
				YAHOO.util.Dom.removeClass(that, 'hover');
				that = null;
			}, 200 );
	} 

	/* get all the menu-trigger divs */
	var menuTriggers = YAHOO.util.Dom.getElementsByClassName('menu-trigger', 'div');

	/* add listeners to menu trigger divs */
	YAHOO.util.Event.addListener( menuTriggers, 'mouseover', showmore );
	YAHOO.util.Event.addListener( menuTriggers, 'mouseout', hideagain );
}
YAHOO.util.Event.onDOMReady(init);

    

Comments

Snippets Manager replied on Thu, 2010/10/28 - 11:22am

This post was really confusing. This is a working example. I will try to repost when functioning properly with YUI Menu, classnames, etc.. Untitled Document ul { margin: 0 } li { float: left; width: 100px; border: 1px solid blue; margin: 0 } ul.hidden-menu { width: 400px; } ul.hidden-menu li { float:left; width: 100px; } li a { display: block; } li a:hover { background: cyan; } .hidden-menu { display: none; } .hover-delay .menu-trigger:hover > .hidden-menu { display: none; } .menu-trigger:hover > .hidden-menu, .menu-trigger.hover > .hidden-menu, .hover-delay .menu-trigger.hover > .hidden-menu { display: block; } #top-nav #services { height: 100%; } /* requires http://yui.yahooapis.com/2.7.0/build/yahoo-dom-event/yahoo-dom-event.js The copy of IE on the terminal server does not work with the menu unless this file is copied locally */ function init() { // break pure css version so we can have the delay YAHOO.util.Dom.addClass(document.body,'hover-delay') // function to show the menu // onmouseover with delay function showmore() { // work around setTimeout context reset var that = this; // left hand needs to know what the right hand is up to if (this.hideWait) clearTimeout(this.hideWait); this.showWait = setTimeout( function() { // add a trigger class YAHOO.util.Dom.addClass(that, 'hover'); // this is supposed to help garbage collection that = null; }, 100 ); } // function to hide the menu // onmouseout with delay function hideagain() { var that = this; if (this.showWait) clearTimeout(this.showWait); this.hideWait = setTimeout( function() { YAHOO.util.Dom.removeClass(that, 'hover'); that = null; }, 200 ); } /* get all the menu-trigger divs */ var menuTriggers = YAHOO.util.Dom.getElementsByClassName('menu-trigger', 'div'); /* add listeners to menu trigger divs */ YAHOO.util.Event.addListener( menuTriggers, 'mouseover', showmore ); YAHOO.util.Event.addListener( menuTriggers, 'mouseout', hideagain ); } YAHOO.util.Event.onDOMReady(init);