Skip to content

Instantly share code, notes, and snippets.

@Mulperi
Last active August 13, 2021 05:46
Show Gist options
  • Save Mulperi/98091ecd615967f3d221a1c1253a5464 to your computer and use it in GitHub Desktop.
Save Mulperi/98091ecd615967f3d221a1c1253a5464 to your computer and use it in GitHub Desktop.
Simple javascript dropdown
/**
HTML:
<header style="display: flex; justify-content: space-between;">
<div class="dropdown--container">
<button>Menu</button>
<div class="dropdown--content">
<ul>
<li><a href="#">Link</a></li>
<li>item</li>
</ul>
</div>
</div>
<div class="dropdown--container">
<button>Menu</button>
<div class="dropdown--content dropdown--right">
This is dropdown 2 content.
</div>
</div>
</header>
**/
/**
CSS:
.dropdown--container {
display: inline;
position: relative;
}
.dropdown--content {
display: none;
border: 2px solid black;
width: 200px;
position: absolute;
}
.dropdown--right {
right: 0;
}
.block {
display: block;
}
**/
// Get all dropdowns, divs that have specific class.
const dropdowns = document.querySelectorAll('.dropdown--container');
const dropdownContents = document.querySelectorAll('.dropdown--content');
// Function to close all dropdowns by removing 'block' class from the content div (2nd child in the container).
function closeAllDropDowns() {
dropdowns.forEach((dropdown) => {
dropdown.children[1].classList.remove("block");
})
}
// Add event listener to document for click event.
document.addEventListener("click", (e) => {
const clickedButton = e.target.localName === "button";
const hasVisibleContent = e.target.nextElementSibling && e.target.nextElementSibling.classList.value.includes("block");
const hasdropdownContainerParent = e.target.parentElement && e.target.parentElement.classList.value.includes("dropdown--container")
let clickedContentArea = false;
/** Check if clicked inside dropdown content area **/
dropdownContents.forEach((dropdownContent) => {
if (dropdownContent.contains(e.target)) {
clickedContentArea = true;
console.log("found")
}
})
// Clicked the button or the content div.
if (hasdropdownContainerParent) {
// If button is clicked and it already has visible content -> remove block class.
if (clickedButton && hasVisibleContent) {
e.target.nextElementSibling.classList.remove("block");
} else if (clickedButton && !hasVisibleContent) {
// First close all dropdowns so only one is open.
closeAllDropDowns();
e.target.nextElementSibling.classList.add("block")
}
} else if (!clickedContentArea) {
// Click outside of dropdown -> close dropdowns.
closeAllDropDowns();
}
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment