2012-12-27 28 views
2

我想教自己一些简单的JQuery,并拿出以下菜单系统。它是基于UL和LI的基本嵌套菜单,其内部的UL使用JQuery .show()显示,并使用.hide()隐藏。该HTML如下: -繁琐的JQuery选择器

<ul id="menu1" class="gtrmenu"> 
     <li><span class="parent"><img class="hidden-bg" src="images/arrow-down.png"/>Single Menu</span> 
      <ul class="children"> 
        <li><a href="#">Blah blah</a></li> 
        <li><a href="#">Drivel</a></li> 
        <li><a href="#">Select something</a></li> 
        <li><a href="#">Choose me!!</a></li> 
      </ul> 
     </li> 
    </ul> 

    <ul id="menu2" class="gtrmenu menugroup2"> 
     <li><span id="menu2click" class="parent"><img class="hidden-bg" src="images/arrow-down.png"/>Grouped Menu</span>  
      <ul class="children"> 
        <li><a href="#">Something here</a></li> 
        <li><a href="#">More Stuff</a></li> 
        <li><a href="#">Waffle etc</a></li> 
      </ul> 
     </li> 
    </ul> 

    <ul id="menu3" class="gtrmenu menugroup2"> 
     <li><span id="menu3click" class="parent"><img class="hidden-bg" src="images/arrow-down.png"/>Search</span> 
      <ul id="searchX" class="children"> 
       <li> 
        <form> 
         <input id="search" type="text" name="firstname"> 
        </form> 
       </li> 
      </ul> 
     </li> 
    </ul>   

    <p>The quick brown fox jumps over the lazy dog</p> 

的Javascript和jQuery是如下: -

function gtrMenu(menuID, groupClass, clickElement) { 

    if (clickElement === undefined) { 
     clickElement = menuID; 
    } 

    $(menuID + ' ul').css("minWidth", $('#menu1').width()); 

    $(clickElement).click(
     function() { 

      if ($(menuID + ' ul.children').is(":hidden")) { 

       // Close any open menus within the same group. 
       if (groupClass !== undefined){ 
        $('ul.gtrmenu.' + groupClass + ' li ul.children:visible').not(menuID).closest('ul.gtrmenu').each(function(index){ 
         //console.log(index + " " + $(this).attr("id")); 
         $(this).find('li .parent img').removeClass('visible-bg').addClass('hidden-bg'); 
         $(this).find('ul.children').hide(); 
        }); 
       } 

       // Change style of arrow image. 
       $(menuID + ' li .parent img').removeClass('hidden-bg').addClass('visible-bg'); 

       // Display the submenu 
       $(menuID + ' ul.children').show(); 

      } 
      else { 

       // Revert style of arrow image. 
       $(menuID + ' li .parent img').removeClass('visible-bg').addClass('hidden-bg'); 

       // Hide the submenu. 
       $(menuID + ' ul.children').hide(); 

      } 
     } 
    ); 
} 

的JavaScript是由以下(运行它不会正确格式化为一部分上面的HTML,所以我在这里添加): -

$(document).ready(function() { 
      gtrMenu("#menu1"); 
      gtrMenu("#menu2", "menugroup2" , "#menu2click"); 
      gtrMenu("#menu3", "menugroup2" , "#menu3click"); 
     }); 

菜单可以是单一的菜单,具体表现为“单一菜单'(menu1);或者可以将其分组,如上面(菜单2 & menu3)中的“分组菜单”(与“搜索”组合)所示。在分组菜单中,一次只能打开一个菜单 - 如果用户打开“分组菜单”并单击“搜索”,则关闭“分组菜单”。我很自豪地说,它的全部工作:-)然而,我在上面的组中找到打开菜单的选择器对我来说似乎非常漫长和繁琐(这是注释掉的console.log行上方的行)。我的问题是:是否有更简单的方法来查找组中已经打开的菜单(以便它们可以关闭)?

在此先感谢。

回答

0

只要你不使用相同的类用于其他目的,实际上可以通过消除不必要的特殊性来缩短选择器。此外,还可以通过使用has选择删除closest方法:

$('.gtrmenu.' + groupClass + ':has(.children:visible)').not(menuID) 

此说,我真的建议你保持专一,只是使其不太可能,你选择一些你不打算。

$('ul.gtrmenu.' + groupClass + ':has(li ul.children:visible)').not(menuID) 
+0

辉煌。我刚刚阅读了关于has()的JQuery文档,这正是我需要的。我认为选择路径直到找到正确的元素,然后退回给父母并不是最好的方式。 – garethTheRed