Home > OS >  Close all child levels of a navigation when parent is closing
Close all child levels of a navigation when parent is closing

Time:03-11

Working on a menu where I want to close all sub navigations when clicking on another link with a sub navigation, it currently only collapses the sub navigation on the same level but not the deeper ones.

Example:

  • Click on A1 > A2A > A3A > A4A
  • Then click on B1
  • Click on A1 again
  • You see that A2A, A3A and A4A are still completely unfolded

$('li.has-children').click(function() {
  
 $(this).children('.wrap').addClass('active');
 
 $(this).closest('ul').children('li').not(this).children('.wrap').removeClass('active');
 
});
ul,
ul li { 
  margin:0;
  padding:0;
  list-style:none;
}

.wrap {
  display: none;
}

.active {
  display: inline-block;
}

.has-children-level1 {
  display:inline-block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
  <li >
    <a >link A1</a>
    <div >
      <ul>
        <li >
          <a >link A2A</a>
          <div >
            <ul>
              <li >
                <a >link A3A</a>
                <div >
                  <ul>
                    <li >
                      <a >link A4A</a>
                    </li>
                  </ul>
                </div>
              </li>
            </ul>
          </div>
        </li>
        <li >
          <a >link A2B</a>
          <div >
            <ul>
              <li >
                <a >link A3B</a>
                <div >
                  <ul>
                    <li >
                      <a >link A4B</a>
                    </li>
                  </ul>
                </div>
              </li>
            </ul>
          </div>
        </li>
      </ul>
    </div>
  </li>
  <li >
    <a >link B1</a>
    <div >
      <ul>
        <li >
          <a >link B2A</a>
          <div >
            <ul>
              <li >
                <a >link B3A</a>
                <div >
                  <ul>
                    <li >
                      <a >link B4A</a>
                    </li>
                  </ul>
                </div>
              </li>
            </ul>
          </div>
        </li>
        <li >
          <a >link B2B</a>
          <div >
            <ul>
              <li >
                <a >link B3B</a>
                <div >
                  <ul>
                    <li >
                      <a >link B4B</a>
                    </li>
                  </ul>
                </div>
              </li>
            </ul>
          </div>
        </li>
      </ul>
    </div>
  </li>
</ul>

CodePudding user response:

I have slightly modified your logic to check if the parent level is clicked, remove the active class from all the child elements.

if($(this).hasClass('has-children')){
  $(this).siblings().find('*').removeClass('active')
}

Also, I have added e.stopPropagation() to prevent bubbling of the click event


Working Code below

$('li.has-children').click(function(e) {
  e.stopPropagation();
  $(this).children('.wrap').addClass('active');


  if ($(this).hasClass('has-children')) {
    $(this).siblings().find('*').removeClass('active')
  }


});
ul,
ul li {
  margin: 0;
  padding: 0;
  list-style: none;
}

.wrap {
  display: none;
}

.active {
  display: inline-block;
}

.has-children-level1 {
  display: inline-block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
  <li >
    <a >link A1</a>
    <div >
      <ul>
        <li >
          <a >link A2A</a>
          <div >
            <ul>
              <li >
                <a >link A3A</a>
                <div >
                  <ul>
                    <li >
                      <a >link A4A</a>
                    </li>
                  </ul>
                </div>
              </li>
            </ul>
          </div>
        </li>
        <li >
          <a >link A2B</a>
          <div >
            <ul>
              <li >
                <a >link A3B</a>
                <div >
                  <ul>
                    <li >
                      <a >link A4B</a>
                    </li>
                  </ul>
                </div>
              </li>
            </ul>
          </div>
        </li>
      </ul>
    </div>
  </li>
  <li >
    <a >link B1</a>
    <div >
      <ul>
        <li >
          <a >link B2A</a>
          <div >
            <ul>
              <li >
                <a >link B3A</a>
                <div >
                  <ul>
                    <li >
                      <a >link B4A</a>
                    </li>
                  </ul>
                </div>
              </li>
            </ul>
          </div>
        </li>
        <li >
          <a >link B2B</a>
          <div >
            <ul>
              <li >
                <a >link B3B</a>
                <div >
                  <ul>
                    <li >
                      <a >link B4B</a>
                    </li>
                  </ul>
                </div>
              </li>
            </ul>
          </div>
        </li>
      </ul>
    </div>
  </li>
</ul>

CodePudding user response:

before setiing the active one reomve all the other active.

$('li.has-children').click(function() {
  var $this = $(this)
  var p = $this.parents('.has-children');

  $('div.wrap').not(this).removeClass('active')

  if(p.length){
  $(`.wrap`,p).not($this.find('.wrap .wrap')).addClass('active')
  }
  else{
    $this.children('.wrap').addClass('active');
  }
  return false
 
});
ul,
ul li { 
  margin:0;
  padding:0;
  list-style:none;
}

.wrap {
  display: none;
}

.active {
  display: block;
}

.has-children-level1 {
  display: block;
} 
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
  <li >
    <a >link A1</a>
    <div >
      <ul>
        <li >
          <a >link A2A</a>
          <div >
            <ul>
              <li >
                <a >link A3A</a>
                <div >
                  <ul>
                    <li >
                      <a >link A4A</a>
                    </li>
                  </ul>
                </div>
              </li>
            </ul>
          </div>
        </li>
        <li >
          <a >link A2B</a>
          <div >
            <ul>
              <li >
                <a >link A3B</a>
                <div >
                  <ul>
                    <li >
                      <a >link A4B</a>
                    </li>
                  </ul>
                </div>
              </li>
            </ul>
          </div>
        </li>
      </ul>
    </div>
  </li>
  <li >
    <a >link B1</a>
    <div >
      <ul>
        <li >
          <a >link B2A</a>
          <div >
            <ul>
              <li >
                <a >link B3A</a>
                <div >
                  <ul>
                    <li >
                      <a >link B4A</a>
                    </li>
                  </ul>
                </div>
              </li>
            </ul>
          </div>
        </li>
        <li >
          <a >link B2B</a>
          <div >
            <ul>
              <li >
                <a >link B3B</a>
                <div >
                  <ul>
                    <li >
                      <a >link B4B</a>
                    </li>
                  </ul>
                </div>
              </li>
            </ul>
          </div>
        </li>
      </ul>
    </div>
  </li>
</ul>

  • Related