Home > Software engineering >  Attempt to Iterate through javascript array only affecting first element
Attempt to Iterate through javascript array only affecting first element

Time:02-22

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";
                });
            }
        }
    });
  • Related