I want it when dropdown.menu
has a "show" class when clicked anywhere in the body or window, dropdown.menu.show
miss the show
class.
The show class is added and removed before using the code (window.onclick = function (event){})
, but when I add this code to the end of the JavaScript code, the show class is not added at all.
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));
//this section is not work!!!
window.onclick = function(event) {
const titleElem = document.querySelector('.dropdown .dropdown--title');
const menu = document.querySelector('.menu');
if (!(event.target == titleElem.nextElementSibling.classList.contains('show'))) {
titleElem.nextElementSibling.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 >
<div >Choose category</div>
<div >
<a href="#" data-category="[15,16,26,27]" >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>
CodePudding user response:
I have used jquery with this it becomes easy to handle the dom. Rest all (html, css) remain same.
$(document).ready(function() {
$(document).on('click', function() {
$('.categories.menu').toggleClass('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);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div >
<div >Choose category</div>
<div >
<a href="#" data-category="[15,16,26,27]" >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>
CodePudding user response:
I added a new attribute data-before
to the dropdown
element and made reference to it from the css part content: attr(data-before);
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");
menu.classList.toggle("show");
menu.classList.contains("show")
? dropdown.setAttribute("data-before", "-")
: dropdown.setAttribute("data-before", " ");
}
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));
document.onclick = function (event) {
if (document.getElementsByClassName("categories menu show").length == 1 && event.target.localName !== "div") {
document.querySelector(".categories.menu").classList.toggle("show");
document.querySelector(".dropdown").setAttribute("data-before", " ");
}
};
.dropdown {
position: relative;
}
.dropdown::before {
content: attr(data-before);
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 data-before=" ">
<div >Choose category</div>
<div >
<a href="#" data-category="[15,16,26,27]" >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>