I am trying to create a dropdown menu in javascript/css, the method I have works but only on the first element.
I'm thinking the solution here is to change subLinkUl to a querySelectorAll and nest a loop inside of the navLink loop. I've tried accomplishing this but still relatively inexperienced with javascript.
The html list is printed dynamically through wordpress.
<div >
<h2>Title 1</h2>
<?php wp_nav_menu( array( 'theme_location' => 'side-menu-services', 'container_class' => 'sidenav-links') ); ?>
<h2>Title 2</h2>
<?php wp_nav_menu( array( 'theme_location' => 'side-menu-about', 'container_class' => 'sidenav-links' ) ); ?>
</div>
const navLink = document.querySelectorAll(".sidenav-links>ul>li");
console.log(navLink);
navLink.forEach((link, index) => {
let subLinkUl = link.querySelector("ul");
if (link.contains(subLinkUl)) {
link.classList.add("dropdown");
}
const subLinkUlHeight =
parseInt(window.getComputedStyle(subLinkUl).height) "px";
subLinkUl.style.marginTop = "-" subLinkUlHeight;
link.addEventListener("mouseenter", () => {
subLinkUl.style.opacity = "1";
subLinkUl.style.marginTop = "0";
subLinkUl.style.transition =
"margin 0.2s ease-in-out, opacity 0.1s ease-in 0.1s";
});
link.addEventListener("mouseleave", () => {
subLinkUl.style.opacity = "0";
subLinkUl.style.marginTop = "-" subLinkUlHeight;
subLinkUl.style.transition =
"margin 0.2s ease-in-out 0.1s, opacity 0.1s ease-in";
});
});
.sidenav-link-wrap {
white-space: nowrap;
transition: opacity 0.5s ease-in-out;
display: grid;
grid-auto-flow: row;
grid-auto-rows: minmax(min-content, max-content);
padding: 110px 2vw 0px;
text-align: left;
overflow-y: scroll;
}
.sidenav-link-wrap h2 {
padding: 25px 0px 15px;
}
.sidenav-links a {
width: 100%;
padding: 10px 0px;
}
.sidenav-links ul {
transition: margin 0.2s ease-in-out, opacity 0.1s ease-in 0.1s;
overflow: hidden;
}
.sidenav-links > ul > li {
overflow: hidden;
}
.sidenav-links > ul > li a,
.sidenav-link-wrap > a {
border-bottom: 1px solid #501622;
width: 100%;
padding: 10px 0px;
display: block;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.sidenav-links > ul > li a::before,
.sidenav-link-wrap > a::before {
content: "";
background-image: url(../images/bullet-arrow.svg);
background-size: 100% 100%;
background-repeat: no-repeat;
display: inline-block;
width: 20px;
height: 20px;
vertical-align: -22.5%;
margin-right: 5px;
margin-left: -25px;
transition: all 0.2s ease-in-out;
}
.sidenav-links > ul > li a:hover::before,
.sidenav-link-wrap > a:hover::before {
margin-left: 0px;
}
.sidenav-links .dropdown > a::before {
background-image: none;
}
.sidenav-links .dropdown > a:hover::before {
margin-left: -25px;
}
.sidenav-links .dropdown > a::after {
content: "";
background-image: url(../images/bullet-arrow-var-02.svg);
background-size: 100% 100%;
background-repeat: no-repeat;
display: inline-block;
width: 15px;
height: 15px;
vertical-align: -20%;
margin-left: 5px;
transform: rotate(90deg);
transition: all 0.2s ease-in-out;
}
.sidenav-links .dropdown ul li a {
font-size: 14px;
margin-left: 15px;
}
.sidenav-links .dropdown ul li > a::before {
background-image: url(../images/bullet-arrow-var-02.svg);
background-size: 15px 15px;
vertical-align: -45%;
margin-right: 5px;
}
.sidenav-links ul li ul {
opacity: 0;
}
CodePudding user response:
Ok, I was correct the solution was to nest a for loop for the subLinkUl within the navLink foreach loop and pass the i index from there.
const navLink = document.querySelectorAll(".sidenav-links>ul>li");
navLink.forEach((link, index) => {
const subLinkUl = link.querySelectorAll(".sub-menu");
for (let i = 0; i < subLinkUl.length; i ) {
if (link.contains(subLinkUl[i])) {
link.classList.add("dropdown");
const subLinkUlHeight =
parseInt(window.getComputedStyle(subLinkUl[i]).height)
"px";
subLinkUl[i].style.marginTop = "-" subLinkUlHeight;
link.addEventListener("mouseenter", () => {
subLinkUl[i].style.opacity = "1";
subLinkUl[i].style.marginTop = "0";
subLinkUl[i].style.transition =
"margin 0.2s ease-in-out, opacity 0.1s ease-in 0.1s";
});
link.addEventListener("mouseleave", () => {
subLinkUl[i].style.opacity = "0";
subLinkUl[i].style.marginTop = "-" subLinkUlHeight;
subLinkUl[i].style.transition =
"margin 0.2s ease-in-out 0.1s, opacity 0.1s ease-in";
});
}
}
});