Skip to content

Instantly share code, notes, and snippets.

@agarciadom
Last active August 5, 2020 08:45
Show Gist options
  • Save agarciadom/7048391 to your computer and use it in GitHub Desktop.
Save agarciadom/7048391 to your computer and use it in GitHub Desktop.
LocalStorage-based dropdown menus with raw JavaScript. The shown/hidden menu state is preserved across loads. By default, everything is shown, and the page also degrades gracefully when JS is disabled. (Look 'ma, no JQuery!)
/*
Simple example of a dropdown menu using HTML5 LocalStorage.
*/
function create_dropdown(menu_id, category_title_class) {
var menu = document.getElementById(menu_id)
var ctitles = menu.getElementsByClassName('category_title')
for (var i = 0; i < ctitles.length; i++) {
var ctitle = ctitles[i]
apply_shown(ctitle, is_shown(ctitle))
ctitle.onclick = toggle_callback(ctitle)
}
}
function toggle_callback(ctitle_elem) {
return function() { set_shown(ctitle_elem, !is_shown(ctitle_elem)) }
}
function get_key(ctitle_elem) {
return 'dropdown category ' + ctitle_elem.childNodes[0].textContent.trim()
}
function is_shown(ctitle_elem) {
var key = get_key(ctitle_elem)
var state = localStorage.getItem(key) || 'true'
return 'true' == state
}
function set_shown(ctitle_elem, shown) {
var key = get_key(ctitle_elem)
localStorage.setItem(key, shown)
apply_shown(ctitle_elem, shown)
}
function apply_shown(ctitle_elem, shown) {
var cbody = ctitle_elem.nextElementSibling
cbody.style.display = shown ? 'block' : 'none'
var arrow = shown ? '▲' : '▼'
if (ctitle_elem.children.length > 0) {
ctitle_elem.children[0].textContent = arrow
}
else {
ctitle_elem.insertAdjacentHTML(
'beforeend',
'<span style="float: right; width: 1.5em">' + arrow + '</span>')
}
}
<?xml version="1.0" encoding="UTF-8"?>
<html>
<head>
<title>HTML5 Drop-downs</title>
<link rel="stylesheet" type="text/css" href="styles.css"/>
<script type="text/javascript" src="dropdown.js"></script>
<script type="text/javascript">
var old_onload = window.onload;
window.onload = function() {
if (old_onload) {
old_onload()
}
create_dropdown('menu', 'category_title')
}
</script>
</head>
<body>
<div id="menu">
<div>
<div class="category_title">Category A</div>
<div>
<div class="entry">Entry A1</div>
<div class="entry">Entry A2</div>
</div>
</div>
<div class="category">
<div class="category_title">Category B</div>
<div>
<div class="entry">Entry B1</div>
<div class="entry">Entry B2</div>
<div class="entry">Entry B3</div>
</div>
</div>
<div class="category">
<div class="category_title">Categoría C</div>
<div>
<div class="entry">Entry C1</div>
<div class="entry">Entry C2</div>
<div class="entry">Entry C3</div>
</div>
</div>
</div>
</body>
</html>
body {
font-family: sans;
}
#menu {
width: 20%;
}
#menu > div {
background-color: #cbeef5;
}
.category_title {
font-weight: bold;
text-align: center;
background-color: #7297e0;
/* Make it look like a link */
cursor: pointer;
/* Make text not selectable to avoid visual artifacts due to double clicking */
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.category_title:hover {
background-color: #72cee0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment