html - jQuery multi-level accordion menu -


i found accordion menus online either did not support multiple levels, or code quite cryptic , didn't want use it. decided, want write own accordion menu, supports arbitrary number of sub-menus.

here have far:

$(document).ready(function() {      // @ beginning top menu items visible    $('.multi-level-accordion-menu > li ul').slideup(0);    console.log('all elements slid up');      // when menu item not active clicked, show next lower level    // when menu item active clicked, hide sub menu items    $('.multi-level-accordion-menu li').click(function() {      var menu_item = $(this);        if (is_active(menu_item)) {        console.log('active menu item clicked');        close_menu_item(menu_item);        } else {        console.log('inactive menu item clicked');        open_menu_item(menu_item);      }    });      console.log('ready!');  });    function open_menu_item(menu_item) {    menu_item.children('ul').slidedown(500);    menu_item.addclass('active-menu-item');  }    function close_menu_item(menu_item) {    console.log('1x');      menu_item.find('ul').each(function(index, elem) {      $(elem).slideup();      return false;    });      menu_item.removeclass('active-menu-item');  }    function is_active(menu_item) {    return menu_item.hasclass('active-menu-item');  }
.multi-level-accordion-menu * {    margin: 0px;    padding: 0px;  }  .multi-level-accordion-menu {    list-style: none;    max-width: 200px;  }  .multi-level-accordion-menu ul {    list-style: none;  }  .multi-level-accordion-menu li {    border-color: #eeeeee;    border-width: 1px;    border-style: solid;    background-color: #303030;    margin: 2px;    padding: 2px;    line-height: 30px;    font-size: 16px;  }  .multi-level-accordion-menu {    color: #dddddd;  }  body {    background-color: #202020;  }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>    <body>    <div>      <ul class='multi-level-accordion-menu'>        <li>item 1          <ul>            <li>item 1.1              <ul>                <li>item 1.1.1</li>                <li>item 1.1.2</li>                <li>item 1.1.3</li>                <li>item 1.1.4</li>              </ul>            </li>            <li>item 1.2</li>            <li>item 1.3</li>            <li>item 1.4</li>            <li>item 1.5</li>            <li>item 1.6</li>          </ul>        </li>        <li>item 2</li>        <li>item 3          <ul>            <li>item 3.1              <ul>                <li>item 3.1.1</li>                <li>item 3.1.2</li>                <li>item 3.1.3</li>                <li>item 3.1.4</li>              </ul>            </li>            <li>item 3.2</li>            <li>item 3.3</li>            <li>item 3.4</li>            <li>item 3.5</li>            <li>item 3.6</li>          </ul>        </li>        <li>item 4</li>        <li>item 5</li>        <li>item 6</li>        <li>item 7</li>      </ul>    </div>  </body>

http://jsfiddle.net/zelphir/1fp03oyq/1/

clicks on top level menu items work, when click item 1 , item 1.1 becomes obvious, lower levels don't work yet. sub-menu opens somehow @ same time top level closes again.

how can achieve following behavior:

  1. a click on 'inactive' menu item makes sub-menu items visible
  2. a click on 'active' menu item hides sub menu items , sub menu items
  3. at beginning items 'inactive'

this should work you.

$('.multi-level-accordion-menu').click(function(e){     var menu_item = $(e.target);      if(is_active(menu_item)) {         console.log('active menu item clicked');         close_menu_item(menu_item);      } else {         console.log('inactive menu item clicked');         open_menu_item(menu_item);               } });  function close_menu_item(menu_item) {     console.log('1x');      menu_item.find('ul').each(function() {         $(this).slideup().find('li').removeclass('active-menu-item');     });      menu_item.removeclass('active-menu-item'); } 

or one/two liner

function close_menu_item(menu_item) {     console.log('1x');        menu_item.removeclass('active-menu-item').find('ul').slideup().     find('li').removeclass('active-menu-item'); } 

in response comment:

in case bubbling causes 'click' method fire on outermost container (.multi-level-accordion-menu).

when click on child element, stored in 'target' property of 'event' object, , click event bubbles until hits outermost container, have defined in jquery selector( again - .multi-level-accordion-menu).

the outermost container sitting there listening 'click' events, when event bubbles it, enters function.

you selecting target element triggered (stored in 'target' property of 'event' object) , performing whatever want on it. since inside function , there no event listeners in there, no more events fire, , there no further bubbling. function completes , no more 'click' events triggered since event has bubbled top.

in original code, listening click events on 'li' elements, when clicked on 'li' element trigger click listener , run function. when function finished event bubble ancestor 'li' element, trigger listener again , run method again. , on.

hope clears bit!


Comments

Popular posts from this blog

android - MPAndroidChart - How to add Annotations or images to the chart -

javascript - Add class to another page attribute using URL id - Jquery -

firefox - Where is 'webgl.osmesalib' parameter? -