Dropdown with Javascript

Asked

Viewed 96 times

1

I am working on a project and came across the following situation: a list of items for a side navigation bar needs buttons that close and open to click (until then beauty). However I need to understand how I do so that when one is opened, the others that have already been opened will close.

<body>
    <nav class="side-navbar">
        <div>
            <a href="#" class="main" id="titulo1">Titulo1</a>
            <ul class="lista">
                    <li><a href="#">item1</a></li>
                    <li><a href="#">item2</a></li>
                    <li><a href="#">item3</a></li>
            </ul>
        </div>

        <div>
            <a href="#" class="main" id="titulo2">Titulo2</a>
            <ul class="lista">
                    <li><a href="#">item1</a></li>
                    <li><a href="#">item2</a></li>
                    <li><a href="#">item3</a></li>
                    <li><a href="#">item4</a></li>
                </ul>
        </div>
        <div>
            <a href="#" class="main" id="titulo3">Titulo3</a>
            <ul class="lista">
                    <li><a href="#">item1</a></li>
                    <li><a href="#">item2</a></li>
                    <li><a href="#">item3</a></li>
                    <li><a href="#">item4</a></li>
            </ul>
       </div>
    </nav>

    <script src="script.js"></script>
</body>

CSS

ul {
    list-style: none;
    display: none;
}

.main{
    font-size: 22px;
    display: block;
}

.toggle{
    display: block;
}

.untuggle{
    display: none;
}

JS

let main = document.querySelectorAll('.main');
let itens = document.querySelectorAll('.lista');

function toggleSide(togle, untugle){
    for(let i = 0; i < main.length; i++){
        main[i].addEventListener('click', function(){

        });
    }
}

4 answers

0


Face the way you set up the script and the CSS is not cool. I made this simplified template that I think will help you.

inserir a descrição da imagem aqui

It works like this, when you click on link vc adds the active class to it, and in css vc defines that link.ativo + .list {display:block}. So whenever you have one link with class . active the list below gets display:block

After that you have to take the classes of the elements, for that I made a forEach(), within the function that adds the active . class, that forEach() first removes the class . active from everyone, and then I add the class . active only in the element clicked with e.currentTarget.classList.add('ativo');

Follows the code

var link = document.querySelectorAll('.main');

function classe(e) {
    e.preventDefault();
    link.forEach( (rmk) => {
        rmk.classList.remove('ativo');
    })
    e.currentTarget.classList.add('ativo');
}

link.forEach( (el) => {
    el.addEventListener('click', classe);
}) 
.lista {
    list-style: none;
    display: none;
}

.main {
    font-size: 22px;
    display: block;
}
.main.ativo + .lista {
    display: block;
}
<nav class="side-navbar">
    <div>
        <a href="#" class="main" id="titulo1">Titulo1</a>
        <ul class="lista">
            <li><a href="#">item1</a></li>
            <li><a href="#">item2</a></li>
            <li><a href="#">item3</a></li>
        </ul>
    </div>

    <div>
        <a href="#" class="main" id="titulo2">Titulo2</a>
        <ul class="lista">
            <li><a href="#">item1</a></li>
            <li><a href="#">item2</a></li>
            <li><a href="#">item3</a></li>
            <li><a href="#">item4</a></li>
        </ul>
    </div>
    <div>
        <a href="#" class="main" id="titulo3">Titulo3</a>
        <ul class="lista">
            <li><a href="#">item1</a></li>
            <li><a href="#">item2</a></li>
            <li><a href="#">item3</a></li>
            <li><a href="#">item4</a></li>
        </ul>
    </div>
</nav>

0

const main = document.querySelectorAll('.main');
const lista = document.querySelectorAll('.lista');

main.forEach(function(el, i) {
  el.addEventListener('click', function() {
  
    lista.forEach(function(el2, i2) {
      el2.style.display = 'none';
    });
    
    this.nextElementSibling.style.display = 'block';
  });
});
ul {
  list-style: none;
  display: none;
}

.main {
  font-size: 22px;
  display: block;
}

.toggle {
  display: block;
}

.untuggle {
  display: none;
}
<nav class="side-navbar">
  <div>
    <a href="#" class="main" id="titulo1">Titulo1</a>
    <ul class="lista">
      <li><a href="#">item1</a></li>
      <li><a href="#">item2</a></li>
      <li><a href="#">item3</a></li>
    </ul>
  </div>

  <div>
    <a href="#" class="main" id="titulo2">Titulo2</a>
    <ul class="lista">
      <li><a href="#">item1</a></li>
      <li><a href="#">item2</a></li>
      <li><a href="#">item3</a></li>
      <li><a href="#">item4</a></li>
    </ul>
  </div>
  <div>
    <a href="#" class="main" id="titulo3">Titulo3</a>
    <ul class="lista">
      <li><a href="#">item1</a></li>
      <li><a href="#">item2</a></li>
      <li><a href="#">item3</a></li>
      <li><a href="#">item4</a></li>
    </ul>
  </div>
</nav>

0

You don’t even need the class .untuggle. If the elements are already invisible with ul display: none, just add/remove the class .toggle.

When you click on an item, that menu opens and another menu opens. If the item opens and you click on it again, it closes.

See the example below for how to do this with Javascript (explanatory comments in the code):

let main = document.querySelectorAll('.main');

for(let i = 0; i < main.length; i++){
   main[i].addEventListener('click', function(){
      
      // busca algum elemento que possua a classe .toggle
      let aberto = document.querySelector(".toggle");
      
      // pega o elemento posterior ao item clicado (ul)
      let lista = this.nextElementSibling;

      // verifica se existe algum elemento com a classe .toggle
      // e que não seja o elemento posterior ao item clicado
      if(aberto && aberto != lista){
         aberto.classList.remove("toggle");
      }
      
      // verifica de a UL possui a classe .toggle
      if(~lista.className.indexOf("toggle")){
         // se possuir, remove a classe
         lista.classList.remove("toggle");
      }else{
         // se não possuir, adiciona a classe
         lista.classList.add("toggle");
      }
   });
}
ul {
    list-style: none;
    display: none;
}

.main{
    font-size: 22px;
    display: block;
}

.toggle{
    display: block;
}
<nav class="side-navbar">
        <div>
            <a href="#" class="main" id="titulo1">Titulo1</a>
            <ul class="lista">
                    <li><a href="#">item1</a></li>
                    <li><a href="#">item2</a></li>
                    <li><a href="#">item3</a></li>
            </ul>
        </div>

        <div>
            <a href="#" class="main" id="titulo2">Titulo2</a>
            <ul class="lista">
                    <li><a href="#">item1</a></li>
                    <li><a href="#">item2</a></li>
                    <li><a href="#">item3</a></li>
                    <li><a href="#">item4</a></li>
                </ul>
        </div>
        <div>
            <a href="#" class="main" id="titulo3">Titulo3</a>
            <ul class="lista">
                    <li><a href="#">item1</a></li>
                    <li><a href="#">item2</a></li>
                    <li><a href="#">item3</a></li>
                    <li><a href="#">item4</a></li>
            </ul>
       </div>
    </nav>

Below the code a little more dry:

let main = document.querySelectorAll('.main');
for(let item of main){
   item.addEventListener('click', function(){
      let aberto = document.querySelector(".toggle");
      let lista = this.nextElementSibling;
      if(aberto && aberto != lista) aberto.classList.remove("toggle");
      lista.classList[~lista.className.indexOf("toggle") ? "remove" : "add"]("toggle");
   });
}

-3

Don’t make a FOR, use CSS class and change the CSS class by Javascript.

Hence you create two "open list" "closed list" classes from there by clicking on one, you ask for change using Document.getElementsByClass('open list') and switch to closed.

This is very easy if you use jQuery

Browser other questions tagged

You are not signed in. Login or sign up in order to post.