Reputation: 505
I have a dropdown in my design that should be deleted when clicked anywhere other than .categories.menu
.
That is, to lose its show class and close the .categories.menu
.
At the end of the code I wrote, if this section (categoriesMenu.classList.remove ("show")
) is run, it will prevent the dropdown of the show class altogether.
so I want to close the menu whenever a user clicks outside the menu.
Thank you in advance for your cooperation.
function toggleClass(elem, className) {
if (elem.className.indexOf(className) !== -1) {
elem.className = elem.className.replace(className, '');
} else {
elem.className = elem.className.replace(/\s+/g, ' ') + ' ' + className;
}
return elem;
}
function toggleDisplay(elem) {
const curDisplayStyle = elem.style.display;
if (curDisplayStyle === 'none' || curDisplayStyle === '') {
elem.style.display = 'block';
} else {
elem.style.display = 'none';
}
}
function toggleMenuDisplay(e) {
const dropdown = e.currentTarget.parentNode;
const menu = dropdown.querySelector('.menu');
toggleClass(menu, 'show');
}
function handleOptionSelected(e) {
toggleClass(e.target.parentNode, 'show');
const id = e.target.id;
const newValue = e.target.textContent + ' ';
const titleElem = document.querySelector('.dropdown .dropdown--title');
titleElem.textContent = newValue;
}
const dropdownTitle = document.querySelector('.dropdown .dropdown--title');
const dropdownOptions = document.querySelectorAll('.dropdown .menu.categories a');
dropdownTitle.addEventListener('click', toggleMenuDisplay);
dropdownOptions.forEach(item => item.addEventListener('click', handleOptionSelected));
var categoriesMenu = document.querySelector('.categories.menu');
window.addEventListener('click', function(event) {
var categoriesMenuShow = categoriesMenu.classList.contains("show");
var isClickInsideElement = categoriesMenu.contains(event.target);
if (isClickInsideElement == categoriesMenuShow ) {
// categoriesMenu.classList.remove("show")
}
});
.dropdown {
position: relative;
}
.dropdown::before {
content: "+";
position: absolute;
width: 1.5rem;
height: 1.5rem;
top: 15px;
right: 0;
color: var(--cbl);
}
.dropdown .dropdown--title {
padding: 0.75rem;
width: 100%;
cursor: pointer;
}
.dropdown .menu {
cursor: pointer;
max-height: 0;
overflow: hidden;
display: flex;
flex-direction: column;
position: absolute;
z-index: 12;
width: 100%;
top: 45px;
right: 0;
background-color: var(--cwh);
transition: max-height 0.3s;
-webkit-transition: max-height 0.3s;
-moz-transition: max-height 0.3s;
-ms-transition: max-height 0.3s;
-o-transition: max-height 0.3s;
box-shadow: 0 3px 20px #ccc;
-webkit-box-shadow: 0 3px 20px #ccc;
-moz-box-shadow: 0 3px 20px #ccc;
}
.dropdown .menu.show {
max-height: 20em !important;
}
.dropdown .menu.show a {
color: var(--cbl);
opacity: 1;
transition: all 0.3s;
-webkit-transition: all 0.3s;
-moz-transition: all 0.3s;
-ms-transition: all 0.3s;
-o-transition: all 0.3s;
transform: translateX(0);
-webkit-transform: translateX(0);
-moz-transform: translateX(0);
-ms-transform: translateX(0);
-o-transform: translateX(0);
}
.dropdown .menu a {
padding: 1rem;
opacity: 0;
color: var(--cbl);
transform: translateX(100%);
-webkit-transform: translateX(100%);
-moz-transform: translateX(100%);
-ms-transform: translateX(100%);
-o-transform: translateX(100%);
}
.dropdown .menu a:nth-child(1) {
transition-delay: 0.2s;
}
.dropdown .menu a:nth-child(2) {
transition-delay: 0.15s;
}
.dropdown .menu a:nth-child(3) {
transition-delay: 0.1s;
}
.dropdown .menu a:nth-child(4) {
transition-delay: 0.05s;
}
.dropdown .menu a:nth-child(5) {
transition-delay: 0s;
}
.dropdown .menu a:not(:last-child) {
border-bottom: 1px solid var(--cblo40);
}
.dropdown .menu a:hover {
background: rgba(0, 0, 0, 0.2);
}
<div class="dropdown">
<div class="dropdown--title">Choose category</div>
<div class="categories menu">
<a href="#" data-category="[15,16,26,27]" class="clicked">All</a>
<a href="http://localhost/discount/product-category/other/" data-category="15">Other</a>
<a href="http://localhost/discount/product-category/electronics/" data-category="16">Electronics</a>
<a href="http://localhost/discount/product-category/sports/" data-category="26">Sports</a>
<a href="http://localhost/discount/product-category/toys/" data-category="27">Toys & Games</a>
</div>
</div>
Upvotes: 2
Views: 92
Reputation: 520
Try this!
function toggleClass(elem, className) {
if (elem.className.indexOf(className) !== -1) {
elem.className = elem.className.replace(className, '');
} else {
elem.className = elem.className.replace(/\s+/g, ' ') + ' ' + className;
}
return elem;
}
function toggleDisplay(elem) {
const curDisplayStyle = elem.style.display;
if (curDisplayStyle === 'none' || curDisplayStyle === '') {
elem.style.display = 'block';
} else {
elem.style.display = 'none';
}
}
function toggleMenuDisplay(e) {
const dropdown = e.currentTarget.parentNode;
const menu = dropdown.querySelector('.menu');
toggleClass(menu, 'show');
}
function handleOptionSelected(e) {
toggleClass(e.target.parentNode, 'show');
const id = e.target.id;
const newValue = e.target.textContent + ' ';
const titleElem = document.querySelector('.dropdown .dropdown--title');
titleElem.textContent = newValue;
}
const dropdownTitle = document.querySelector('.dropdown .dropdown--title');
const dropdownOptions = document.querySelectorAll('.dropdown .menu.categories a');
dropdownTitle.addEventListener('click', toggleMenuDisplay);
dropdownOptions.forEach(item => item.addEventListener('click', handleOptionSelected));
var categoriesMenu = document.querySelector('.categories.menu');
window.addEventListener('click', function(event) {
var categoriesMenuShow = categoriesMenu.classList.contains("show");
var isClickInsideElement = categoriesMenu.contains(event.target);
if (isClickInsideElement == categoriesMenuShow ) {
// categoriesMenu.classList.remove("show")
}
});
//newly added code to determine outside clicks
var ignoreClickOnMeElement = document.getElementById('dropdown');
document.addEventListener('click', function(event) {
var isClickInsideElement = ignoreClickOnMeElement.contains(event.target);
if (!isClickInsideElement) {
categoriesMenu.classList.remove("show");
}
});
.dropdown {
position: relative;
}
.dropdown::before {
content: "+";
position: absolute;
width: 1.5rem;
height: 1.5rem;
top: 15px;
right: 0;
color: var(--cbl);
}
.dropdown .dropdown--title {
padding: 0.75rem;
width: 100%;
cursor: pointer;
}
.dropdown .menu {
cursor: pointer;
max-height: 0;
overflow: hidden;
display: flex;
flex-direction: column;
position: absolute;
z-index: 12;
width: 100%;
top: 45px;
right: 0;
background-color: var(--cwh);
transition: max-height 0.3s;
-webkit-transition: max-height 0.3s;
-moz-transition: max-height 0.3s;
-ms-transition: max-height 0.3s;
-o-transition: max-height 0.3s;
box-shadow: 0 3px 20px #ccc;
-webkit-box-shadow: 0 3px 20px #ccc;
-moz-box-shadow: 0 3px 20px #ccc;
}
.dropdown .menu.show {
max-height: 20em !important;
}
.dropdown .menu.show a {
color: var(--cbl);
opacity: 1;
transition: all 0.3s;
-webkit-transition: all 0.3s;
-moz-transition: all 0.3s;
-ms-transition: all 0.3s;
-o-transition: all 0.3s;
transform: translateX(0);
-webkit-transform: translateX(0);
-moz-transform: translateX(0);
-ms-transform: translateX(0);
-o-transform: translateX(0);
}
.dropdown .menu a {
padding: 1rem;
opacity: 0;
color: var(--cbl);
transform: translateX(100%);
-webkit-transform: translateX(100%);
-moz-transform: translateX(100%);
-ms-transform: translateX(100%);
-o-transform: translateX(100%);
}
.dropdown .menu a:nth-child(1) {
transition-delay: 0.2s;
}
.dropdown .menu a:nth-child(2) {
transition-delay: 0.15s;
}
.dropdown .menu a:nth-child(3) {
transition-delay: 0.1s;
}
.dropdown .menu a:nth-child(4) {
transition-delay: 0.05s;
}
.dropdown .menu a:nth-child(5) {
transition-delay: 0s;
}
.dropdown .menu a:not(:last-child) {
border-bottom: 1px solid var(--cblo40);
}
.dropdown .menu a:hover {
background: rgba(0, 0, 0, 0.2);
}
<div class="dropdown" id="dropdown">
<div class="dropdown--title">Choose category</div>
<div class="categories menu">
<a href="#" data-category="[15,16,26,27]" class="clicked">All</a>
<a href="http://localhost/discount/product-category/other/" data-category="15">Other</a>
<a href="http://localhost/discount/product-category/electronics/" data-category="16">Electronics</a>
<a href="http://localhost/discount/product-category/sports/" data-category="26">Sports</a>
<a href="http://localhost/discount/product-category/toys/" data-category="27">Toys & Games</a>
</div>
</div>
Thanks and best regards!
Upvotes: 2