<link href="//netdna.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
<script src="//netdna.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
<script src="//code.jquery.com/jquery-1.11.1.min.js"></script>
<!------ Include the above in your HEAD tag ---------->
<nav class="navbar navbar-inverse" data-toggle="navbar-mega-menu">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar-collapse-megamenu">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#" onclick="javascript:return false;"> <!-- I hate inline JS, but this is just for this demo because I hate jerky demos more. -->
[logo]
</a>
</div>
<div class="collapse navbar-collapse" id="navbar-collapse-megamenu">
<ul class="nav navbar-nav">
<li class="dropdown mega-dropdown dropdown-slide" data-toggle="mega-menu">
<a href="#" class="dropdown-toggle">Megamenu 1</a>
<div class="dropdown-menu mega-dropdown-menu">
<div class="container-fluid">
<h1>Hi there #1!</h1>
<p>Try clicking the next menu, "Megamenu 2".</p>
</div>
</div>
</li>
<li class="dropdown mega-dropdown dropdown-slide" data-toggle="mega-menu">
<a href="#" class="dropdown-toggle" data-toggle="mega-menu">Megamenu 2</a>
<div class="dropdown-menu mega-dropdown-menu">
<div class="container-fluid">
<h1>Hi there #2!</h1>
<p>Try clicking outside the menu area.</p>
</div>
</div>
</li>
</ul>
</div>
</div>
</nav>
<div class="container">
<div class="row">
<div class="col-sm-12">
<p>Try it out like this:</p>
<ol>
<li>Click "Megamenu 1" - opens with vertical animation</li>
<li>Click "Megamenu 2" - opens with horizontal animatin, closes the first menu in the background</li>
<li>Click outside the menu - closes with vertical animation</li>
</ol>
<div class="alert alert-dismissible alert-warning">
<strong>Abandonded</strong> because I need a version that animates smoothly when the menus are different high and this can't. So feel free to refactor the code. ;)
</div>
</div>
</div>
</div>
/* Seems like Bootsnipp.com needs some convincing to give me the whole iframe to click in */
html,
body {
height: 100%;
}
/* Borrowed from http://bootsnipp.com/snippets/featured/mega-menu-with-tabs-navigation */
.mega-dropdown {
position: static !important;
}
.mega-dropdown-menu {
padding: 20px 15px 15px;
width: 100%;
}
.dropdown-slide:not(.open) > .dropdown-menu {
padding: 0;
}
.dropdown-slide.open.current > .dropdown-menu {
z-index: 2000;
}
.dropdown-slide.dropdown-sliding:not(.open) > .dropdown-menu {
display: none !important;
}
.dropdown-slide.dropdown-slide-y > .dropdown-menu {
max-height: 0;
-webkit-transition: max-height 0.25s ease-out;
-o-transition: max-height 0.25s ease-out;
transition: max-height 0.25s ease-out;
overflow: hidden;
display: block;
border: none;
}
.dropdown-slide.dropdown-slide-y.open > .dropdown-menu {
max-height: 600px;
-webkit-transition: max-height 0.25s ease-in;
-o-transition: max-height 0.25s ease-in;
transition: max-height 0.25s ease-in;
}
.dropdown-slide.dropdown-slide-x > .dropdown-menu {
-webkit-transform: translate(100%, 0%);
-ms-transform: translate(100%, 0%);
-o-transform: translate(100%, 0%);
transform: translate(100%, 0%);
-webkit-transition: -webkit-transform 0.25s ease-out;
-moz-transition: -moz-transform 0.25s ease-out;
-o-transition: -o-transform 0.25s ease-out;
transition: transform 0.25s ease-out;
display: block;
border: none;
}
.dropdown-slide.dropdown-slide-x.open > .dropdown-menu {
-webkit-transform: translate(0%, 0%);
-ms-transform: translate(0%, 0%);
-o-transform: translate(0%, 0%);
transform: translate(0%, 0%);
-webkit-transition: -webkit-transform 0.25s ease-in;
-moz-transition: -moz-transform 0.25s ease-in;
-o-transition: -o-transform 0.25s ease-in;
transition: transform 0.25s ease-in;
}
// I was going to clean this up, but then noticed that it wasn't going to fulfill my needs of variable sized menus so I think I'm abandoning it...
// Solution adapted from http://stackoverflow.com/a/25196101.
$(function() {
$('[data-toggle="navbar-mega-menu"]').each(function () {
var $rootNav = $(this);
var $body = $('body');
var $collapse = $rootNav.find('.collapse');
var $items = $rootNav.find('[data-toggle="mega-menu"]');
var $menus = $items.find('.dropdown-menu');
var animationSpeed = 250;
var timeout;
var timeout2;
function runAfterAnimation(func) {
clearTimeout(timeout);
timeout = setTimeout(func, animationSpeed);
}
function closeAllMenus() {
$items.removeClass('open dropdown-slide-x');
$items.addClass('dropdown-slide-y');
}
$items.each(function() {
var $root = $(this);
var $link = $root.find('.dropdown-toggle');
var $menu = $root.find('.dropdown-menu');
var $otherItems = $items.not($root);
var $otherMenus = $menus.not($menu);
$root.addClass('dropdown-slide-y');
// Hide from mobile.
//$root.addClass('dropdown-slide'); // Should I set animation from JS? There should be a way to toggle animations.
$collapse.on('show.bs.collapse', function () {
$root.removeClass('dropdown-slide');
});
$collapse.on('hidden.bs.collapse', function () {
$root.addClass('dropdown-slide');
});
// Handle menu clicks.
$link.on('click', function (event) {
var wasOpen = $root.hasClass('open');
if (wasOpen) {
$root.removeClass('open');
runAfterAnimation(closeAllMenus);
} else {
$root.addClass('open current');
$root.removeClass('dropdown-sliding'); // If the callbacks were cancelled, it might have this when it shouldn't and that would make the menu not show.
$otherItems.addClass('dropdown-sliding');
$otherItems.removeClass('current');
runAfterAnimation(function () {
$otherItems.removeClass('open dropdown-slide-y');
$otherItems.addClass('dropdown-slide-x dropdown-sliding');
$root.addClass('dropdown-slide-y');
$root.removeClass('dropdown-slide-x');
clearTimeout(timeout2); // Hack! :/ Do this with animation-end events in js or delayed animation start in css instead?
timeout2 = setTimeout(function() {
$otherItems.removeClass('dropdown-sliding');
}, animationSpeed);
});
}
return false;
});
// Close when clicking outside the menu area.
$body.on('click', function(e) {
if (!$root.is(e.target) && $root.has(e.target).length===0 && $rootNav.find('.open').has(e.target).length===0) {
$root.removeClass('open current');
closeAllMenus();
}
});
});
});
});