简体   繁体   中英

How to ensure only 1 nav bar is dropped when clicking on specific element?

I have this situation where I am clicking on a button in my nav bar and would like the corresponding nav bar to drop, I've drafted the HTML and attempted to create the JavaScript for this but haven't been able to successfully implement it.

 const dropdownButtons = document.querySelectorAll(".dropdownButton"); const dropdownNav = document.querySelectorAll(".dropdown"); const navBar = document.querySelector("#navBar"); function toggleDropdown() { dropdownNav.forEach((x => x.classList.toggle("show"))) } dropdownButtons.forEach((btn) => { btn.addEventListener("click", (e) => { const button = e.target; toggleDropdown(button) }) })
 @import url('https://fonts.googleapis.com/css2?family=Overpass:wght@300;600&family=Ubuntu:wght@400;500;700&display=swap'); * { padding: 0; margin: 0; box-sizing: border-box; font-family: 'Overpass', sans-serif; font-family: 'Ubuntu', sans-serif; }:root { --dark-red-cta: hsl(356, 100%, 66%); --light-red-cta: hsl(355, 100%, 74%); --dark-blue-heading: hsl(208, 49%, 24%); --white: hsl(0, 0%, 100%); --grayish-blue-footer: hsl(240, 2%, 79%); --dark-grayish-blue: hsl(207, 13%, 34%); --very-dark-blue: hsl(240, 10%, 16%); } /* NAVBAR */ nav { padding: 2em 10em; } nav img { padding-right: 2em; } nav, .siteNav { display: flex; align-items: center; justify-content: space-between; } ul { list-style-type: none; } li { display: inline; } button img { margin-left: .5em; } button { cursor: pointer; background: none; border: none; color: white; font-size: .9em; } header { text-align: center; background-image: url(/images/bg-pattern-intro-desktop.svg), linear-gradient(100deg, hsl(13, 100%, 72%), hsl(353, 100%, 62%)); background-size: 218%, auto; background-position: 25% 52%; height: 75vh; border-radius: 0 0 0 6em; } header h1 { color: white; font-size: 3em; font-weight: 500; padding: 2em 0.5em 0; } header p { color: white; padding: 0 0 2em 0; }.startButton, .loginButton { background-color: white; color: var(--dark-red-cta); border-radius: 30px; width: 140px; padding: 1.1em; font-weight: bold; }.learnMoreButton { color: white; border-radius: 30px; width: 140px; padding: 1.1em; border: 1px solid var(--white); font-weight: bold; } /* For the drop down */.dropdownItem { position: relative; }.dropdown { position: absolute; background: var(--white); border-radius: 8px; padding: 1em; text-align: left; margin-top: 1em; height: 14em; width: 10em; display: flex; flex-direction: column; justify-content: space-evenly; visibility: hidden; }.show { visibility: visible; }.rotateImg { transform: rotate(90deg); }.dropdown li a { color: black; text-decoration: none; }.dropdown li a:hover { font-weight: bold; }
 <nav> <div class="siteNav"> <img src="/images/logo.svg" alt="Blogr logo"> <ul id="navBar"> <li class="dropdownItem"> <button class="dropdownButton">Product <img src="/images/icon-arrow-light.svg" alt="Drop down arrow"> </button> <ul class="dropdown dropdown-content"> <li><a href="#">Overview</a></li> <li><a href="#">Pricing</a></li> <li><a href="#">Marketplace</a></li> <li><a href="#">Features</a></li> <li><a href="#">Integrations</a></li> </ul> </li> <li class="dropdownItem"> <button class="dropdownButton">Company <img src="/images/icon-arrow-light.svg" alt="Drop down arrow"> </button> <ul class="dropdown dropdown-content"> <li><a href="#">About</a></li> <li><a href="#">Team</a></li> <li><a href="#">Our Blog</a></li> <li><a href="#">Careers</a></li> </ul> </li> <li class="dropdownItem"> <button class="dropdownButton">Connect <img src="/images/icon-arrow-light.svg" alt="Drop down arrow"> </button> <ul class="dropdown dropdown-content"> <li><a href="#">Contact</a></li> <li><a href="#">Newsletter</a></li> <li><a href="#">LinkedIn</a></li> </ul> </li> </ul> </div> <div class="login"> <button class="loginButton">Login</button> <button class="signUpButton">Sign Up</button> </div> </nav>

I'm currently successfully able to correspond a click and assign the correct class using this method but the only issue is that it adds it to all 3 drop downs and I just cannot wrap my head around event bubbling so would appreciate a little bit of hand holding for this example.

I am looping through the buttons and then triggering a function which should then make the relative drop down visible by updating it's visibility. This works and it only shows the 3rd option because it updates all 3 classes instead of one.

I tried using a current target approach on this but wasn't able to get it to work since I couldn't add a classList to e.target. Could someone point out to me where I'm going wrong on this one?

EDIT: Added CSS file as it would be relevant to see the positioning of the elements understandably.

Pass a prop index so that you would toggle the class .show only to that particular dropdown and not all

const dropdownButtons = document.querySelectorAll(".dropdownButton");
const dropdownNav = document.querySelectorAll(".dropdown");
const navBar = document.querySelector("#navBar");

function toggleDropdown(ind) {
    dropdownNav[ind].classList.toggle("show")
}

dropdownButtons.forEach((btn, index) => {
    btn.addEventListener("click", (e) => {
        const button = e.target;
        toggleDropdown(index)
    })
})

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM