2

我正在尝试自学一些简单的 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");
        });

菜单可以是单个菜单,如“Single Menu”(menu1)所示;或者它可以被分组,如上面的“分组菜单”(与“搜索”分组)所示(菜单2和菜单3)。在分组菜单中,一次只能打开一个 - 如果用户打开了“分组菜单”并单击“搜索”,则“分组菜单”将关闭。

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

提前致谢。

4

1 回答 1

0

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

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

这就是说,我实际上建议您保留特异性,只是为了减少您选择您不打算选择的东西的可能性。

$('ul.gtrmenu.' + groupClass + ':has(li ul.children:visible)').not(menuID)
于 2012-12-27T11:22:16.737 回答