4

我必须建立一个点击触发的小下拉系统。我已经设法处理“点击 div”问题(感谢之前发布的这个问题)。

我可以隐藏当前下拉菜单,单击另一个下拉菜单的触发器或单击下拉菜单本身。所以,问题是这些:

  1. 点击当前下拉菜单的触发器没用;当其他事情正常工作时,下拉菜单不会消失
  2. 当前下拉列表中单击(例如: .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 我设法解决了这个问题,所以这是当前的工作代码 $(document).ready(function(){

        $("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(...

也在这里

$(this).closest(".nav").find(".dropdown-menu").not(... 我使它更通用 $(".dropdown-menu").not(...那是因为我想隐藏所有打开的下拉菜单。以前的行为是只考虑一种目标和一个原点区域(例如:也许我需要这些下拉菜单以及标题和某种工具栏内的内容)。


编辑 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")是否有做下拉下拉菜单的事情。如果是,什么也不做。如果不是,那么这确实意味着我点击了任何地方,没有点击下拉菜单的位置。

4

1 回答 1

2

它认为这样的事情应该可以完成:

$(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保持在切换到的任何状态。
于 2012-12-19T01:52:11.293 回答