Submenu levels do not work properly Vanilla JS

I am making a menu with pure Vanilla JS, because I want it to implement it in an Angular 8 project. It is working good at some point, because it opens the hidden menu very good. The thing is that when I want to open a second level hidden menu , then it closes everything. For example if you click in 'Soluciones' link, then it opens the submenu very good. After that you must be able to click 'Correo y herramientas' in order to show a second level hidden menu, which is: Correo 1, Correo 2, Correo 3 links; but before showing this last links, it closes everything. I have a codepen link to show this: https://codepen.io/Bungo808/pen/ZEBpmXG Any advice would be helpfull!!

My HTML


<div class="red">

    <nav id="nav" class="sub-menu open">
      <ul class="list-unstyled">
        <li id="subb">
          <a class="link">Quiénes somos</a>
          <img id="iplus" class="splus" src="../../assets/img/splus.svg" alt="">
          <ul id="smenu" >
            <li>
                <a class="link">Sobre eSource</a>
            </li>
            <li>
                <a class="link">Amarello</a>
            </li>
          </ul>
        </li>
        <li id="subb">
          <a class="link">Soluciones</a>
          <img id="iplus" class="splus" src="../../assets/img/splus.svg" alt="">
          <ul id="smenu" >
            <li id="subb">
                <a class="link">Correo y herramientas</a>
                <ul>
                    <li><a class="link">Correo 1</a></li>
                    <li><a class="link">Correo 2</a></li>
                    <li><a class="link">Correo 3</a></li>
                </ul>
            </li>
            <li id="subb">
                <a class="link">Infrastructure as a Service</a>
                <ul>
                    <li><a class="link">Infra 1</a></li>
                    <li><a class="link">Infra 2</a></li>
                    <li><a class="link">Infra 3</a></li>
                </ul>
            </li>
          </ul>
        </li>
    
      </ul>
    </nav>
    <div class="overlay"></div>
</div>

My JS

let list_items = document.querySelectorAll('#subb');

// Show Submenu
    for (let i = 0; i < list_items.length; i++) {
      list_items[i].addEventListener("click", show);
    }

    function show() {
      this.classList.toggle("myClass");
      console.log('I clicked it!')
    }


A part of my CSS, which is the responsible to open the hidden menu


.sub-menu {
  padding: 0 0 0 2%;
  left: 0px;
  top: 0;
  transition: all 0.3s ease;
  height: 100%;
  width: 280px;
  position: fixed;
  margin: 0;
  background-color: #f9f9f9;
  border-radius: 0;
  z-index: 10;
  overflow: hidden;
}

.sub-menu > ul {
  width: 100%;
  height: 100%;
  margin-top: 60px;
}
.sub-menu li {
  position: relative;
  display: block;
  list-style: none;
  padding: 2px 0 2px 14px;
  margin-left: 0;
  cursor: pointer;
  color: white;
  transition: all 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55);
  &:first-child{
    // border: 1px solid red;
  }
}
.sub-menu li a {
  color: #40465f;
  font-size: 16px;
  font-weight: 300;
  width: 100%;
  display: block;
  line-height: 22px;
  padding: 6px 0;
  &:hover{
    color: #2487FC;
    text-decoration: none;
  }
}
.sub-menu ul ul li a {
  color: #40465f;
  font-size: 14px;
  font-weight: 300;
  width: 100%;
  line-height: 22px;
  padding: 6px 0;
  &:hover{
    color: #2487FC;
    text-decoration: none;
  }
}
.sub-menu ul ul ul li a {
  color: #40465f;
  font-size: 14px;
  font-weight: 300;
  width: 100%;
  display: block;
  line-height: 22px;
  padding: 6px 0;
  &:hover{
    color: #2487FC;
    text-decoration: none;
  }
}

.sub-menu ul ul{
  display: none;
  background: white;
}

#subb.myClass > ul{
  display: block;
}

.sub-menu ul ul ul{
  display: none;
  border: 1px solid red;
}

Upvotes: 1

Views: 78

Answers (1)

Randy Casburn
Randy Casburn

Reputation: 14175

The click event is propagating over and over again. So eventually the class gets toggled off. To prevent this add .stopPropagation(); to your show() function like this:

function show(e) {
  e.stopPropagation();
  this.classList.toggle("myClass");
  console.log('I clicked it!')
}

Upvotes: 1

Related Questions