[英]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
時,很明顯,較低級別的菜單項仍不起作用。 子菜單打開,但同時又以某種方式再次關閉頂層菜單。
如何實現以下行為:
這應該為您工作。
$('.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.