Mootools Mega Drop Down Menu

Anyone else noticing a trend in web browsing these days? Well I certainly have and so have the good people over at SitePoint.com. Mega Menu’s are similar to your standard navigation bars, but tend to have some javascript to help you navigate down the many levels you might find within one, but they are rife with issues, such as complexity, hidden content and use-ability concerns. So what is the solution when you have a lot of content or products that you wish to show in your nav without angering or frustrating your users, easy, enter the Mega Drop Down Menu. They have the extra cool and unique advantage of having larger area’s for sub-links or inner pages, sometimes even including images, descriptions and popular items in that category within the newly shown element.

Here is a decent example of a Mega Drop Down Menu to illustrate what I’m talking about. But it certainly takes way too long to load, and uses images for the drop down box, which I personally don’t like because you have to wait for it to load on a slow connection, such as this wireless laptop I’m on.

So I was looking around for a better implementation of a mega drop down menu and noticed that a couple I found were using jQuery wizardry to effectively prevent instant hover effects, because you don’t want the mega drop down from appearing every time a user rolls over your top level navigation items, and a few were using neat CSS3 effects instead of images.

Then I thought it would be nice to have all the positives in one Mega Drop Down combined together and since there were already a few jQuery implementations doing one or the other, I figured I’d do it in MooTools, since I still have a penchant for that framework, so I’ve converted one of the jQuery plugins to MooTools for you all, added some other nifty features and given you some basic css to play with. So without further ad-due, here is the code for a MooTools – Mega Drop Down Menu .

Demo

View Demo :: MooTools

The HTML

 Grab it from the example page, as there is quite a bit of markup for the mega drops

The MooTools Javascript

Element.implement({
	megaMenu: function(f,g){

		var cfg = {
			sensitivity: 7,
			interval: 100,
			timeout: 0
		};
		
		cfg = $extend(cfg, g ? { over: f, out: g } : f );
		var cX, cY, pX, pY;

		var track = function(ev) {
			cX = ev.page.x;
			cY = ev.page.y;
		};

		var compare = function(ev,ob) {
			ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t);
			if ( ( Math.abs(pX-cX) + Math.abs(pY-cY) ) < cfg.sensitivity ) {
				$(ob).removeEvent("mousemove",track);
				ob.hoverIntent_s = 1;
				return cfg.over.apply(ob,[ev]);
			} else {
				pX = cX; pY = cY;
				ob.hoverIntent_t = setTimeout( function(){compare(ev, ob);} , cfg.interval );
			}
		};

		var delay = function(ev,ob) {
			ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t);
			ob.hoverIntent_s = 0;
			return cfg.out.apply(ob,[ev]);
		};

		var handleHover = function(e) {
			
			var p = (e.type == "mouseover" ? e.fromElement : e.toElement) || e.relatedTarget;
			while ( p && p != this ) { try { p = p.parentNode; } catch(e) { p = this; } }
			if ( p == this ) { return false; }
			var ev = $extend({},e);
			var ob = this;
			if (ob.hoverIntent_t) { ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t); }

			if (e.type == "mouseover") {
				pX = ev.pageX; pY = ev.pageY;
				$(ob).addEvent("mousemove",track);
				if (ob.hoverIntent_s != 1) { ob.hoverIntent_t = setTimeout( function(){compare(ev,ob);} , cfg.interval );}
			} else {
				$(ob).removeEvent("mousemove",track);
				if (ob.hoverIntent_s == 1) { ob.hoverIntent_t = setTimeout( function(){delay(ev,ob);} , cfg.timeout );}
			}
			
		};

		return this.addEvent('mouseover', handleHover).addEvent('mouseout', handleHover)
	}
});

Paste this code into your scripts file. It will simply implement a new MooTools method for you, that will allow you to add the megaMenu functionality to any element/s that you desire.

Usage

window.addEvent('domready', function() {
    // Function fired on mouseover  
    function addMega(){
      $(this).addClass("hovering");
    }
    // Function fired on mouseout
    function removeMega(){
      $(this).removeClass("hovering");
    }

    var megaConfig = {
         interval: 200,
         sensitivity: 4,
         timeout: 200,
         over: addMega,
         out: removeMega
    };
	
    $$("li.mega").megaMenu(megaConfig)

});

Ok, so the first two functions "addMega" and "removeMega" are completely and utterly not needed, but you will most likely want to include them so that you can apply a class name or some other property to items that have the megaMenu method attached.

megaConfig is simply your set up options, explained below.

  • interval: The number of milliseconds the function waits between reading/comparing mouse coordinates.
  • sensitivity: If the mouse travels fewer than this number of pixels between polling intervals, then the "over" function will be called.
  • timeout: A simple delay, in milliseconds, before the "out" function is called

Credits

I can't claim full credit for the code and examples, I've borrowed heavily for times sake from the following sites.

Go here for the jQuery mega drop down plugin

Go here for the full SitePoint article on mega drop downs

Enjoy...

3 Comments

  1. tatac says:

    There is way to add fade-in\out effects?

  2. Chris says:

    Is there a way to keep the main top menu highlighed or hover active while in the mega menu?

  3. Simon says:

    Yeah of course. I’m not sure if I have added it this release but it is rather simple to add a classname of active to the parent link, the one you hovered over to reveal the menu. Something like el.addClass(‘active’);

    el is the element that is hovered over, then add some CSS styles for .active

    Easy 🙂

Post a Comment