Skip to content

Instantly share code, notes, and snippets.

@eyy
Created May 28, 2019 08:12
Show Gist options
  • Save eyy/eb041c7817c33402cf4fbc5eef9acc11 to your computer and use it in GitHub Desktop.
Save eyy/eb041c7817c33402cf4fbc5eef9acc11 to your computer and use it in GitHub Desktop.
Drop-right: a simple dropdown to the right
<div>
<ul>
<li><a href="#">1</a></li>
<li><a href="#">2</a></li>
<li>
3 +
<ul class="drop-right">
<li><a href="#">3.1</a></li>
<li><a href="#">3.2</a></li>
<li>
3.3 +
<ul>
<li><a href="#">3.3.1</a></li>
<li><a href="#">3.3.2</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
<script>
Array.from(document.querySelectorAll('.drop-right'))
.forEach(initDrop)
function initDrop (el) {
const parent = el.parentNode
let insideDrop = false
let insideParent = false
function toggle (show) {
if (!show) {
el.style.display = 'none'
return
}
let {top, left, width} = parent.getBoundingClientRect()
el.style.top = top
el.style.left = left + width - 1
el.style.display = 'block'
}
document.body.appendChild(el)
parent.addEventListener('mouseenter', () => {
insideParent = true
toggle(insideParent || insideDrop)
})
parent.addEventListener('mouseleave', () => {
insideParent = false
toggle(insideParent || insideDrop)
})
el.addEventListener('mouseenter', () => {
insideDrop = true
toggle(insideParent || insideDrop)
})
el.addEventListener('mouseleave', () => {
insideDrop = false
toggle(insideParent || insideDrop)
})
document.body.addEventListener('keydown', ev => {
if (ev.key === 'Escape')
toggle(false)
})
}
</script>
<style>
div {
width: 400px;
margin: 0 auto;
overflow: scroll;
border: 1px solid #cf9bfc;
padding: 1em;
}
ul {
width: 200px;
list-style: none;
margin: 0;
padding: 0;
border-bottom: 1px solid lightgrey;
}
li {
position: relative;
padding: .5em;
border: 1px solid lightgrey;
border-bottom: 0;
background: white;
}
.drop-right, .drop-right ul {
display: none;
position: absolute;
left: 100%;
top: -1px;
}
li:hover > ul {
display: block;
}
</style>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment