繁琐的JQuery选择器

时间:2012-12-27 11:15:29

标签: jquery jquery-selectors

我试图教自己一些简单的JQuery,并提出以下菜单系统。它是一个基本的嵌套UL和LI基于菜单,内部UL用JQuery .show()显示,并用.hide()隐藏。 HTML如下: -

    <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");
        });

菜单可以是单个菜单,如单个菜单&#39;所示。 (MENU1);或者它可以分组,如“分组菜单”所示。 (上面有&#39;搜索&#39;)(menu2&amp; menu3)。在分组菜单中,一次只能打开一个 - 如果用户有分组菜单&#39;打开并点击“搜索”,“分组菜单”和“#39;分组菜单&#39;关闭。

我很自豪地说这一切都有效:-)但是,我在上面组中查找打开菜单的选择器对我来说似乎很长很麻烦(它是在注释掉的console.log之上的行)线)。我的问题是:是否有更简单的方法来查找组中已经打开的菜单(以便可以关闭它们)?

提前致谢。

1 个答案:

答案 0 :(得分:0)

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

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

这就是说,我实际上会建议你保持特异性,只是为了让你不太可能选择你不想要的东西。

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