jquery – 多个下拉菜单:处理它们的正确方法是什么?

我必须构建一个由点击触发的小型下拉系统.我已经设法如何处理“点击div”问题(感谢
this之前发布的问题).

我可以隐藏当前下拉列表,点击另一个下拉列表的触发器或点击下拉列表本身.那么,问题是这些:

>点击当前下拉列表的触发器,它没用;当其他东西正常工作时,下拉列表不会消失
>单击当前下拉列表(例如:.divider项目),会导致下拉列表消失

所以,这里是html代码(假设我在标题中有多个下拉列表)

    ...
    <div id="header" class="navbar">
        <div class="line">
            <a href="#" class="logo">Site Name</a>
            <ul class="nav right">
                <li>
                    <a href="#" class="has-drop">Item 1</span>
                    <ul class="dropdown-menu">
                        <li><a href="#">Action A</a></li>
                        <li><a href="#">Action B</a></li>
                        <li><a href="#">Action C</a></li>
                        <li class="divider"></li>
                        <li><span>Inline note</span></li>
                    </ul>
                </li>
                <li>
                    <a class="has-drop" href="#">Item 2</a>
                    <ul class="dropdown-menu">
                        <li><a href="#">Action D</a></li>
                        <li><a href="#">Action E</a></li>
                        <li><a href="#">Action F</a></li>
                        <li class="divider"></li>
                        <li><a href="#">Action G</a></li>
                    </ul>
                </li>
            </ul>
        </div>
    </div> <!-- end #header -->
    ...

这实际上是我在一个专用文件中使用的JS代码

    $(document).ready(function(){

        $("html").on({
            click: function(e) {
                $(".dropdown-menu.opened").toggleClass("opened");
            }
        });

        $(".nav > li > a").on({
            click: function(e){
                e.stopPropagation();

                $(".dropdown-menu.opened").toggleClass("opened"); // should close each .dropdowns before opening the current one
                $(e.target).siblings(".dropdown-menu").toggleClass("opened");
            }
        });

    });

当我重新点击其触发器时,为什么你认为下拉列表不会隐藏?因为在$(“.nav> li> a”).on()里面几乎做同样的事情?

此外,有一种方法可以防止下拉某些孩子被点击时隐藏下拉?但也许这与另一个问题有关,我不知道.

最后但并非最不重要的:在您看来,这是完成整个事情的正确方法吗?

谢谢大家

编辑:感谢@ Beetroot-Beetroot我管理了如何解决问题,所以这是当前的工作代码
        $(文件).就绪(函数(){

        $("html").on("click", function(e) {
            $(".dropdown-menu.opened").removeClass("opened");
        });

        $(".nav").find("li :first-child").on("click", function(e) {
            e.preventDefault();
            e.stopPropagation();

            var $thisMenu = $(this).siblings(".dropdown-menu").toggleClass("opened");
            $(".dropdown-menu").not($thisMenu).removeClass("opened");
        });

    });

“秘密”是巧妙地使用.not(),我现在更了解它.

我刚刚将目标(可以< a>或< span>)更改为更通用的目标.从长远来看不确定表现,但肯定是一个很好的起点.

$(".nav").find("a.has-drop").on(...

$(".nav").find("li :first-child").on(...

也在这里

$(本).closest( “NAV ”).找到(“ 下拉菜单”).未(…
我这样更通用了
   $( “下拉菜单”).未(…
那是因为我想要隐藏所有打开的下拉菜单.之前的行为只考虑了一种目标而且只考虑了一个原点区域(例如:我可能也需要这些下拉列表以及内部某些工具栏内的这些下拉菜单).

编辑2:@ Beetroot-Beetroot再次帮助了我.正如他所建议的那样,当我在jsFiddle中移植当前代码时,突然之间解决方案就出现了.所以现在$(“html”).on(“click”,…部分看起来像这样

    $("html").on("click", function(e) {

        if ( $(e.target).hasClass("dropdown-menu") || $(e.target).parents(".dropdown-menu").length ) {
            // do nothing, basically
        } else {
            $(".dropdown-menu.opened").removeClass("opened");
        }
    });

基本上我只是看看来自$(“html”)的点击是否有关于下拉列表的宽度.如果是的话,什么也不做.如果不是,那么这确实意味着我点击了任何一个但不是下拉列表的位置.

最佳答案 它认为这样的事情应该做的工作:

$(document).ready(function() {
    $("html").on('click', function(e) {
        $(".dropdown-menu.opened").removeClass("opened");
    });
    $(".nav").find("a.has-drop").on('click', function(e) {
        e.preventDefault();
        e.stopPropagation();
        var $thisMenu = $(this).siblings(".dropdown-menu").toggleClass("opened");
        $(this).closest(".nav").find(".dropdown-menu").not($thisMenu).removeClass("opened");
    });
});

未经测试

备注:

> removeClass()在几个地方替换toggleClass().
>秘诀是首先切换$thisMenu,然后在下一行中使用not($thisMenu)以确保$thisMenu保持在切换到的任何状态.

点赞