简体   繁体   English

打开另一个下拉菜单时如何关闭下拉菜单

[英]How to close a dropdown menu when another one is opening

I can't figure out how to close one submenu when another one is open.当另一个子菜单打开时,我不知道如何关闭一个子菜单。 I'm not sure if html is needed here, so I'm just attaching JS code here:我不确定这里是否需要 html,所以我只是在这里附上 JS 代码:

问题演示

 const burgerBtn = document.querySelector(".header__burger"), menu = document.querySelector(".menu"), body = document.querySelector(".body"), filter = document.querySelector(".filter"), blockFilter = document.querySelectorAll(".block-filter"), dropdown = document.querySelectorAll(".block-filter__dropdown"); if (filter) { blockFilter.forEach(item => { item.addEventListener("click", event => { item.querySelector(".block-filter__dropdown").classList.toggle("block-filter__dropdown_state_active"); item.querySelector(".block-filter__icon").classList.toggle("block-filter__icon_state_active"); if (event.target.classList.contains("block-filter__item")) { item.querySelector(".block-filter__value").textContent = event.target.textContent; } }) }) }
 <div class="filter hero__filter"> <form class="filter__form"> <div class="filter__block block-filter"> <div class="block-filter__button"> <div class="block-filter__header"> <span class="block-filter__type">Purpose</span> <div class="block-filter__icon"></div> </div> <span class="block-filter__value">Buy</span> </div> <div class="block-filter__dropdown"> <span class="block-filter__item">Buy</span> <span class="block-filter__item">Sell</span> </div> </div>

Sure, just remove the class from the active one first:当然,只需先从活动中删除 class :

item.addEventListener("click", (event) => {
    // get active, and if it exists, remove active
    document.querySelector(".block-filter__dropdown_state_active")?.classList.remove("block-filter__dropdown_state_active");

    item.querySelector(".block-filter__dropdown").classList.toggle(
        "block-filter__dropdown_state_active"
    );
    item.querySelector(".block-filter__icon").classList.toggle(
        "block-filter__icon_state_active"
    );
    if (event.target.classList.contains("block-filter__item")) {
        item.querySelector(".block-filter__value").textContent =
            event.target.textContent;
    }
});

We use ?.我们用?. here to prevent us from going further (and causing an error) if there is no active dropdown already.如果还没有活动的下拉菜单,这里可以防止我们走得更远(并导致错误)。

What you need to do is look for a currently active item first and "de-activate" them.您需要做的是首先查找当前活动的项目并“停用”它们。 You should also check that the currently active item is not the clicked item as you already have logic defined for that.您还应该检查当前活动的项目是否不是单击的项目,因为您已经为此定义了逻辑。

I've expanded on your snippet to create a solution.我已经扩展了您的代码段以创建解决方案。

NOTE: It might be useful creating a separate function/s for handling to "activate" and "de-activate" code where you pass in a .block-filter element.注意:在传入.block-filter元素的地方创建一个单独的函数来处理“激活”和“取消激活”代码可能很有用。

 const burgerBtn = document.querySelector(".header__burger"), menu = document.querySelector(".menu"), body = document.querySelector(".body"), filter = document.querySelector(".filter"), blockFilter = document.querySelectorAll(".block-filter"), dropdown = document.querySelectorAll(".block-filter__dropdown"); if (filter) { blockFilter.forEach(item => { item.addEventListener("click", event => { const active_dropdown = document.querySelector(".block-filter__dropdown_state_active"); if(active_dropdown.== null){ // get parent until we find ".block-filter" const active_item = active_dropdown.closest(";block-filter"). // check it's not the current item if(active_item.== null && active_item.== item){ // apply same logic as below to remove active state active_item.querySelector(";block-filter__dropdown").classList.remove("block-filter__dropdown_state_active"). active_item.querySelector(";block-filter__icon").classList.remove("block-filter__icon_state_active"). } } // your original logic item.querySelector(";block-filter__dropdown").classList.toggle("block-filter__dropdown_state_active"). item.querySelector(";block-filter__icon").classList.toggle("block-filter__icon_state_active"). if (event.target.classList.contains("block-filter__item")) { item.querySelector(".block-filter__value");textContent = event.target.textContent; } }) }) }
 /* base styles */ * { box-sizing: border-box; } html { font-family: sans-serif; background-color: #f3f3f3; }.filter.hero__filter { width:600px; margin:auto; border: 2px solid #eee; background-color: #fff; }.filter__form { display:flex; }.filter__block { flex: 1; padding: 5px; position: relative; }.block-filter__header { font-weight:600; font-size:12px; color: #555; }.block-filter__dropdown { display:none; position:absolute; top:100%; left:0; right:0; background-color:#fff; border: 1px solid #ccc; box-shadow: 0 2px 4px rgb(0 0 0 / 10%); border-radius:4px; }.block-filter__dropdown_state_active { display: block; }.block-filter__item { padding: 5px 10px; display:block; border-bottom: 1px solid #eee; }.block-filter__item:last-child { border-bottom: none; }
 <div class="filter hero__filter"> <form class="filter__form"> <div class="filter__block block-filter"> <div class="block-filter__button"> <div class="block-filter__header"> <span class="block-filter__type">Purpose</span> <div class="block-filter__icon"></div> </div> <span class="block-filter__value">Buy</span> </div> <div class="block-filter__dropdown"> <span class="block-filter__item">Buy</span> <span class="block-filter__item">Sell</span> </div> </div> <div class="filter__block block-filter"> <div class="block-filter__button"> <div class="block-filter__header"> <span class="block-filter__type">Second</span> <div class="block-filter__icon"></div> </div> <span class="block-filter__value">Alpha</span> </div> <div class="block-filter__dropdown"> <span class="block-filter__item">Bravo</span> <span class="block-filter__item">Charlie</span> <span class="block-filter__item">Delta</span> </div> </div> </form> </div>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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