Search code examples
javascripthtmlecmascript-6ecmascript-2016

toggle menu with one menu open at a time in pure javascript


I want to make menu toggle and one item from menu is open at a time. I am able to open one item at a time but unable to do toggle at the same time.

var navclick = document.getElementsByClassName("js-dropdown");
var navContent = document.getElementsByClassName('-arrow-link-content');
for (var i = 0; i < navclick.length; i++) {
    navclick[i].onclick = function () {
      if (this.parentNode.querySelector('div.-arrow-link-content').classList.contains('nav-active')) {
        this.parentNode.querySelector('div.-arrow-link-content').classList.remove('nav-active'); 
      }
      else {
        this.parentNode.querySelector('div.-arrow-link-content').classList.add('nav-active');
      }
    }
  }
.-arrow-link-content {
  display:none;
}
.nav-active{ display:block;}
<ul class="c-icons" id="c-iconslist">
                    <li>
                        <div class="c-icons__text js-dropdown">heading 1</div>
                     <div class="c-icons__textdropdown -arrow-link-content"> Content 1</div>
                    </li>
                       <li>
                        <div class="c-icons__text js-dropdown">heading 2</div>
                     <div class="c-icons__textdropdown -arrow-link-content"> Content 2</div>
                    </li>
                </ul>

if anyone have any suggestions.. please share.. Thanks in advance


Solution

  • Since at most one element can be open at a time, we just have to look for that one elment and close it first if it exists, before we open an unopened element

    var navclick = document.getElementsByClassName("js-dropdown");
    var navContent = document.getElementsByClassName('-arrow-link-content');
    for (var i = 0; i < navclick.length; i++) {
        navclick[i].onclick = function () {
          if (this.parentNode.querySelector('div.-arrow-link-content').classList.contains('nav-active')) {
            this.parentNode.querySelector('div.-arrow-link-content').classList.remove('nav-active'); 
          }
          else {
            try {
              // if an open element exists, close it first
              this.parentNode.parentNode.querySelector('.nav-active').classList.remove('nav-active');
             }
              catch (error){ 
                // Error occurs when no open elment exists, in that case: Do nothing
              }
            this.parentNode.querySelector('div.-arrow-link-content').classList.add('nav-active');
          }
        }
      }
     
    .-arrow-link-content {
      display:none;
    }
    .nav-active{ display:block;}
    <ul class="c-icons" id="c-iconslist">
                        <li>
                            <div class="c-icons__text js-dropdown">heading 1</div>
                         <div class="c-icons__textdropdown -arrow-link-content"> Content 1</div>
                        </li>
                           <li>
                            <div class="c-icons__text js-dropdown">heading 2</div>
                         <div class="c-icons__textdropdown -arrow-link-content"> Content 2</div>
                        </li>
                    </ul>