Long sub menus with native scrollbar
by Vasil Dinkov
HTML
<script src="https://vadikom.github.io/smartmenus/src/jquery.smartmenus.js"></script>
<link rel="stylesheet" href="https://vadikom.github.io/smartmenus/src/css/sm-core-css.css">
<link rel="stylesheet" href="https://vadikom.github.io/smartmenus/src/css/sm-blue/sm-blue.css">
<script src="https://code.jquery.com/jquery-1.11.3.min.js"></script>
<nav role="navigation">
<!-- Sample menu definition -->
<ul id="main-menu" class="sm sm-blue">
<li><a href="http://www.smartmenus.org/">Home</a></li>
<li><a href="#">Long sub 1</a>
<ul>
<li><a href="#">Dummy item</a></li>
<li><a href="#">Dummy item</a></li>
<li><a href="#">Dummy item</a></li>
<li><a href="#">Dummy item</a></li>
<li><a href="#">A pretty long text to test the default subMenusMaxWidth:20em setting for the sub menus</a></li>
<li><a href="#">Dummy item</a></li>
<li><a href="#">Dummy item</a></li>
<li><a href="#">Dummy item</a></li>
<li><a href="#">Dummy item</a></li>
<li><a href="#">Dummy item</a></li>
<li><a href="#">Dummy item</a></li>
<li><a href="#">Dummy item</a></li>
<li><a href="#">Dummy item</a></li>
<li><a href="#">Dummy item</a></li>
<li><a href="#">Dummy item</a></li>
<li><a href="#">A pretty long text to test the default subMenusMaxWidth:20em setting for the sub menus</a></li>
<li><a href="#">Dummy item</a></li>
<li><a href="#">Dummy item</a></li>
<li><a href="#">Dummy item</a></li>
<li><a href="#">Dummy item</a></li>
<li><a href="#">Dummy item</a></li>
<li><a href="#">Dummy item</a></li>
<li><a href="#">Dummy item</a></li>
<li><a href="#">Dummy item</a></li>
<li><a href="#">Dummy item</a></li>
<li><a href="#">Dummy item</a></li>
<li><a href="#">A pretty long text to test the default subMenusMaxWidth:20em setting for the sub menus</a></li>
<li><a href="#">Dummy...
CSS
/* IGNORE: Unrelated generic demo styles */
body {
margin: 8px;
background: #fff;
color: #aaa;
font: 16px/1.5em 'Helvetica Neue', Helvetica, Arial, sans-serif;
}
.demo-text {
margin: 3em 22px;
}
.demo-text p {
margin-bottom: 1em;
}
.demo-text a {
color: #999;
}
JavaScript
// SmartMenus init
$(function() {
$('#main-menu').smartmenus({
subMenusSubOffsetX: 1,
subMenusSubOffsetY: -8
});
});
// Set proper max-height for sub menus in desktop view
$('#main-menu').bind('beforeshow.smapi', function(e, menu) {
var $sub = $(menu),
hasSubMenus = $sub.find('ul').length && !$sub.hasClass('mega-menu');
// if the sub doesn't have any deeper sub menus, apply max-height
if (!hasSubMenus) {
var obj = $(this).data('smartmenus');
if (obj.isCollapsible()) {
$sub.css({
'overflow-y': '',
'max-height': ''
});
} else {
var $a = $sub.dataSM('parent-a'),
$li = $a.closest('li'),
$ul = $li.parent(),
level = $sub.dataSM('level'),
$win = $(window),
winH = $win.height(),
winY = $win.scrollTop(),
subY = winY;
// if the parent menu is horizontal
if ($ul.parent().is('[data-sm-horizontal-sub]') || level == 2 && !$ul.hasClass('sm-vertical')) {
var itemY = $a.offset().top,
itemH = obj.getHeight($a),
subOffsetY = level == 2 ? obj.opts.mainMenuSubOffsetY : obj.opts.subMenusSubOffsetY,
subY = itemY + itemH + subOffsetY;
}
$sub.css({
'max-height': winH + winY - subY
});
}
}
});
// Set overflow-y: auto for sub menus in desktop view
// this needs to be done on the 'show.smapi' event because the script resets overflow on menu show
$('#main-menu').bind('show.smapi', function(e, menu) {
var $sub = $(menu),
hasSubMenus = $sub.find('ul').length && !$sub.hasClass('mega-menu');
// if the sub doesn't have any deeper sub menus, apply overflow-y: auto
if (!hasSubMenus) {
var obj = $(this).data('smartmenus');
if (!obj.isCollapsible()) {
// the timeout fixes an issue in jQuery 3
// it may need to be adjusted if you use a longer "showDuration" than the default
setTimeout(function() {
$sub.css('overflow-y', 'auto');
}, 1);
}
}
});