Instantly share code, notes, and snippets.
Created
November 21, 2011 20:30
-
Star
1
(1)
You must be signed in to star a gist -
Fork
0
(0)
You must be signed in to fork a gist
-
Save perifer/1383829 to your computer and use it in GitHub Desktop.
Responsive menu
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function($){ | |
$.fn.adaptiveMenu = function(options) { | |
// Create some defaults, extending them with any options that were provided | |
var settings = $.extend({ | |
resize: true, | |
resizeDelay: 20 | |
}, options), | |
resizeTimer = false, | |
els = this; | |
if (settings.resize) { | |
$(window).resize(function() { | |
if (resizeTimer !== false) { | |
clearTimeout(resizeTimer); | |
} | |
resizeTimer = setTimeout(function() {resize(els);}, settings.resizeDelay); | |
}); | |
}; | |
return els.each(function() { | |
var aM = {}; | |
aM.$el = $(this); | |
aM.$list = $("ul", aM.$el); | |
aM.$menuItems = $('li', aM.$list); | |
aM.menuItemCount = aM.$menuItems.length; | |
aM.lastMenuItem = aM.menuItemCount - 1; | |
aM.menuWidth = aM.$list.width(); | |
aM.lastRemovedWidth = 0; | |
aM.$dropdown = $('<ul class="am-dropdown"></ul>').append(aM.$list.html()).insertAfter(aM.$el); | |
aM.$dropdownItems = $('li', aM.$dropdown); | |
aM.$more = $('<li class="am-more"><a href="#">More…</a></li>').appendTo(aM.$list).hide(); | |
aM.moreWidth = aM.$more.width(); | |
// Store data on the element, used by the resize event. | |
aM.$el.data('adaptiveMenu', aM); | |
aM.$more.click(function(){ | |
aM.$dropdown[aM.dropdownVisible ? 'hide' : 'show'](); | |
aM.dropdownVisible = !aM.dropdownVisible; | |
return false; | |
}); | |
checkMenu(aM); | |
}); | |
}; | |
/** Helper functions **/ | |
function checkMenu(aM) { | |
if (doRemove(aM)) { | |
aM.$more.show(); | |
while(doRemove(aM)) { | |
updateItems(aM); | |
}; | |
} | |
else if (doAdd(aM)) { | |
// Add items | |
while(doAdd(aM)) { | |
updateItems(aM, true); | |
if (aM.lastMenuItem + 1 === aM.menuItemCount) { | |
aM.$more.hide(); | |
aM.menuWidth = aM.$list.width(); | |
} | |
} | |
}; | |
} | |
function doRemove(aM) { | |
return aM.lastMenuItem > -1 && aM.$el.width() < aM.menuWidth; | |
} | |
function doAdd(aM) { | |
return aM.lastMenuItem < aM.menuItemCount - 1 && | |
// Subtract the .more element with when showing the last element. | |
aM.$el.width() > aM.menuWidth + aM.lastRemovedWidth - ((aM.lastMenuItem === aM.menuItemCount - 2) ? aM.moreWidth : 0); | |
} | |
function updateItems(aM, add) { | |
var n = (add ? 1 : 0), | |
itemN = aM.lastMenuItem + n; | |
$item = $(aM.$menuItems[itemN]); | |
$(aM.$dropdownItems[itemN]).css('display', (add ? 'none' : 'block')); | |
aM.lastRemovedWidth = $(aM.$menuItems[itemN + n]).width(); | |
$item[add ? 'removeClass' : 'addClass']('hide'); | |
aM.menuWidth = aM.$list.width(); | |
aM.lastMenuItem = itemN - 1 + n; | |
}; | |
function resize(els) { | |
els.each(function() { | |
var aM = $(this).data('adaptiveMenu'); | |
if (aM.dropdownVisible) { | |
aM.$dropdown.hide(); | |
aM.dropdownVisible = false; | |
} | |
checkMenu(aM); | |
}); | |
}; | |
})(jQuery); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" | |
"http://www.w3.org/TR/html4/loose.dtd"> | |
<html class="no-js" lang="en"> | |
<script src="http://code.jquery.com/jquery.js" type="text/javascript" charset="utf-8"></script> | |
<script type="text/javascript" charset="utf-8"> | |
// Remove "no-js" class from <html> element, if it exists, and add "js" class. | |
document.documentElement.className = document.documentElement.className.replace(/\bno-js\b/, '') + ' js'; | |
</script> | |
<head> | |
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> | |
<style type="text/css" media="screen"> | |
body, ul, li { | |
margin: 0; | |
padding: 0; | |
} | |
.header { | |
position: relative; | |
} | |
.menu { | |
width: 100%; | |
background: red; | |
overflow: hidden; | |
} | |
.menu ul { | |
float: left; | |
white-space: nowrap; | |
line-height:1; | |
font-size: 0; /* prevent whitespace issue when using inline-block */ | |
} | |
.menu ul li { | |
list-style: none; | |
margin-left: 1px; | |
font-size: 16px; /* override font-size: 0 */ | |
display: inline-block; | |
/* IE7 inline block fix */ | |
zoom: 1; | |
*display: inline; | |
} | |
.menu li.hide { | |
display: none; | |
} | |
.dropdown { | |
position: absolute; | |
display: none; | |
width: 100%; | |
} | |
.dropdown li { | |
display: none | |
} | |
/* Theme */ | |
.header { | |
margin: 50px; | |
} | |
.menu { | |
background: silver; | |
min-width: 52px; | |
} | |
.menu ul li a { | |
padding: 0.25em 20px; | |
background: #000; | |
color: #fff; | |
display: block; | |
} | |
.dropdown { | |
background: red; | |
} | |
</style> | |
</head> | |
<body> | |
</body> | |
<div class="header"> | |
<div class="menu"> | |
<ul> | |
<li><a href="#">1 Home</a></li><li><a href="#">2 News</a></li> | |
<li><a href="#">3 Client & Cases</a></li> | |
<li><a href="#">4 Our Process</a></li> | |
<li><a href="#">5 We are Wonderleap</a></li> | |
<li><a href="#">6 About Us</a></li><li><a href="#">7 Contact</a></li> | |
</ul> | |
</div> | |
</div> | |
<p><a href="#">LINK</a></p> | |
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p> | |
<script type="text/javascript" charset="utf-8"> | |
var $el = $(".menu"), | |
$list = $("ul", $el), | |
$menuItems = $('li', $list), | |
menuItemCount = $menuItems.length, | |
lastMenuItem = menuItemCount - 1, | |
menuWidth = $list.width(), | |
lastRemovedWidth = 0, | |
$dropdown = $('<ul class="dropdown"></ul>').append($list.html()).insertAfter($el), | |
$dropdownItems = $('li', $dropdown), | |
$more = $('<li class="more"><a href="#"> V </a></li>').appendTo($list).hide(), | |
moreWidth = $more.width(), | |
resizeTimer = false, | |
dropdownVisible = false; | |
function updateItems(add) { | |
var n = (add ? 1 : 0), | |
itemN = lastMenuItem + n; | |
$item = $($menuItems[itemN]); | |
$($dropdownItems[itemN]).css('display', (add ? 'none' : 'block')); | |
lastRemovedWidth = $($menuItems[itemN + n]).width(); | |
$item[add ? 'removeClass' : 'addClass']('hide'); | |
menuWidth = $list.width(); | |
lastMenuItem = itemN - 1 + n; | |
}; | |
function doRemove() { | |
return lastMenuItem > -1 && $el.width() < menuWidth; | |
} | |
function doAdd() { | |
return lastMenuItem < menuItemCount - 1 && | |
$el.width() > menuWidth + lastRemovedWidth - ((lastMenuItem === menuItemCount - 2) ? moreWidth : 0); | |
} | |
function checkMenu() { | |
if (doRemove()) { | |
$more.show(); | |
while(doRemove()) { | |
updateItems(); | |
}; | |
} | |
else if (doAdd()) { | |
// Add items | |
while(doAdd()) { | |
updateItems(true); | |
if (lastMenuItem + 1 === menuItemCount) { | |
$more.hide(); | |
menuWidth = $list.width(); | |
} | |
} | |
}; | |
} | |
$more.click(function(){ | |
$dropdown[dropdownVisible ? 'hide' : 'show'](); | |
dropdownVisible = !dropdownVisible; | |
}); | |
$(window).resize(function() { | |
if (dropdownVisible) { | |
$dropdown.hide(); | |
dropdownVisible = false; | |
} | |
if (resizeTimer !== false) { | |
clearTimeout(resizeTimer); | |
} | |
resizeTimer = setTimeout(checkMenu, 20); | |
}); | |
checkMenu(); | |
//$(elm).adaptiveMenu({'resize':false, 'dropdownEvent':'hover'}); | |
</script> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment