繁体   English   中英

jQuery多层手风琴菜单

[英]jQuery multi-level accordion menu

我在网上找到了一些手风琴菜单,但是它们要么不支持多个级别,要么代码很神秘,我不想使用它。 因此,我决定要编写自己的手风琴菜单,该菜单支持任意数量的子菜单。

这是我到目前为止的内容:

 $(document).ready(function() { // at the beginning only the top menu items are visible $('.multi-level-accordion-menu > li ul').slideUp(0); console.log('all elements slid up'); // when a menu item which is not active is clicked, show the next lower level // when a menu item which is active is clicked, hide all its 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/

单击顶层菜单项会起作用,但是当我单击Item 1 Item 1.1然后再单击Item 1.1时,很明显,较低级别的菜单项仍不起作用。 子菜单打开,但同时又以某种方式再次关闭顶层菜单。

如何实现以下行为:

  1. 单击“无效”菜单项将使其子菜单项可见
  2. 单击“活动”菜单项会隐藏其子菜单项及其子菜单项
  3. 一开始,所有项目都是“无效”的

这应该为您工作。

$('.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');
}

或一两个衬垫

function close_menu_item(menu_item) {
    console.log('1x');  

    menu_item.removeClass('active-menu-item').find('ul').slideUp().
    find('li').removeClass('active-menu-item');
}

针对您的评论:

在这种情况下,起泡是导致“ click”方法在最外面的容器上触发的原因(.multi-level-accordion-menu)。

当您单击一个子元素时,该子元素将存储在“事件”对象的“目标”属性中,并且单击事件会冒泡直到其击中您在jQuery选择器中定义的最外面的容器(再次-.multi -level-accordion-menu)。

最外面的容器坐在那里侦听“单击”事件,因此当该事件冒泡到它时,它将进入该函数。

然后,您选择触发所有元素的目标元素(存储在“事件”对象的“目标”属性中)并对其执行所需的操作。 由于您现在位于函数内部,并且那里没有事件侦听器,因此不会再触发任何事件,因此不会再冒泡了。 该功能完成,并且不再触发“点击”事件,因为该事件已经冒泡到顶部。

在您的原始代码中,您正在侦听所有“ li”元素上的单击事件,因此,当您单击“ li”元素时,它将立即触发点击侦听器,然后运行您的函数。 然后,当函数完成时,事件将冒泡到一个祖先“ li”元素,再次触发侦听器并再次运行该方法。 等等。

希望这可以清除它!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM