Gabriel747 Gabriel747 - 4 months ago 13
HTML Question

Need JavaScript help. dropdown menu issue

can you please run the snippet and see my issue. All I need is to fix arrows to work correct. Right now everything is good when clicking the same element to open and close the drop down. But if you try to open the drop down clicking on first element then click on second element the first drop down will close but arrow will remain how it was in open position.



function toggleClass(element, className) {
if (!element || !className) {
return;
}

var classString = element.className,
nameIndex = classString.indexOf(className);
if (nameIndex == -1) {
classString += ' ' + className;
} else {
classString = classString.substr(0, nameIndex) + classString.substr(nameIndex + className.length);
}
element.className = classString;
}

function dropDown(el) {

Array.from(document.querySelectorAll('.overlayOpen'))
.filter(elem => elem !== el.nextElementSibling)
.forEach(element => element.classList.remove('overlayOpen'));

toggleClass(el.nextElementSibling, 'overlayOpen');
toggleClass(el, 'listPoints');
toggleClass(el, 'arrUp');
}

ul {
width: 200px;
}
li {
margin: 0;
font-size: 20px;
line-height: 50px;
width: 100%;
cursor: pointer;
background-color: red;
overflow: hidden;
position: relative;
}
.overlayOpen {
opacity: 1 !important;
height: 50px !important;
width: 100% !important;
}
.overlay {
width: 100%;
z-index: 1000;
background-color: green;
overflow: hidden;
max-width: 800px;
opacity: 0;
height: 0;
width: 0;
-webkit-transition: height 0.2s, opacity 0.2s ease;
-moz-transition: height 0.2s, opacity 0.2s ease;
-o-transition: height 0.2s, opacity 0.2s ease;
-ms-transition: height 0.2s, opacity 0.2s ease;
transition: height 0.2s, opacity 0.2s ease;
}
.arrUp::before {
content: '';
position: absolute;
right: 20px;
top: 18px;
margin-top: 0;
width: 1em;
height: 1em;
border-top: 0.3em solid #A0A09F;
border-right: 0.3em solid #A0A09F;
-moz-transform: rotate(-45deg);
-webkit-transform: rotate(-45deg);
transform: rotate(-45deg);
}
.listPoints::after {
content: '';
position: absolute;
right: 20px;
top: 7px;
margin-top: 0;
width: 1em;
height: 1em;
border-top: 0.3em solid #A0A09F;
border-right: 0.3em solid #A0A09F;
-moz-transform: rotate(135deg);
-webkit-transform: rotate(135deg);
transform: rotate(135deg);
}

<ul>
<li id="1" class="listPoints" onclick='dropDown(this)'>example</li>
<li id="overlay_1" class='overlay'>Hidden stuff</li>
</ul>

<ul>
<li id="2" class="listPoints" onclick='dropDown(this)'>example</li>
<li id="overlay_2" class='overlay'>Hidden stuff</li>
</ul>





Thanks

Answer

I am not a big fan of your style, but if you have to do it this way, then you need to reverse all of the effects of "opening" the dropdown when another is opened :

Array.from(document.querySelectorAll('.overlayOpen'))
    .filter(elem => elem !== el.nextElementSibling)
    .forEach(element => {element.classList.remove('overlayOpen'); 
            element.previousElementSibling.classList.remove('arrUp');
            element.previousElementSibling.classList.add('listPoints');
    })