当单击该下拉菜单之外的任何区域时,如何使用javascript/jquery隐藏该下拉菜单

How do I hide this drop down menu using javascript/jquery when any area outside of it is clicked?

本文关键字:下拉菜单 何使用 javascript jquery 隐藏 区域 单击 任何      更新时间:2023-09-26

现在,我单击#headerNav,菜单会按预期下降,但当我单击菜单外的任何位置时,它都没有效果。

我哪里错了?

我的HTML:

   <header>
      <div id='headerContent'>
        <div id='LogoHolder'>
        </div>
        <nav id='headerNav'>
          <ul>
            <li id='photoThumbnail'></li>
            <li id='currentUser'>
              <ul class="dropdownMenu">
                <li>link1</li>
                <li>link2</li>
                <li>link3</li>
                <li>link4</li>
                <li>link5</li>
                <li>link6</li>
              </ul>
            </li>
          </ul>
        </nav>
      </div>
    </header>

我的JS:

$("#headerNav").click(function(e) {
  return $(".dropdownMenu").addClass('homeMenuClass').toggle()(e.stopPropagation());
});
$("html").click(function(e) {
  return $(".dropDownMenu").addClass('menuGone').toggle();
});

CSS:

.homeMenuClass {
                position:absolute;
            background-color:white;
            border: {
                        top: 2px solid $main-background-color;
                 right: 1px solid $main-background-color;
                 bottom: 1px solid $main-background-color;
                     left: 1px solid $main-background-color;
            }
            top:37px;
            right:-40px;
            height:245px;
            width:200px;
            font-weight:bold;
            color:gray;
            -webkit-box-shadow: 0 10px 6px -6px #777;
            -moz-box-shadow: 0 10px 6px -6px #777;
                        box-shadow: 0 10px 6px -6px #777;
                  a {
                    color:gray;
                  }
}
.menuGone {
    display:none !important;
}

我研究过类似的问题并尝试过解决方案,但似乎都不起作用。问候

更新:。。对切换变量函数有点困惑。

$(function() {
       var button = $("#headerNav"),
    menu = $(".dropdownMenu", button),
    toggle = function(e) {
        e.stopPropagation();
        if (menu.hasClass('open')) {
            menu.toggle().removeClass('open').addClass('homeMenuClass');
        } else {
            menu.toggle().addClass('open').addClass('homeMenuClass');
        }
    };
button.click(toggle);
$(document).click(function(e) {
    if (($(e.target).parents('#headerNav').length === 0 || e.target.id === 'headerNav') && menu.hasClass('open')) {
        toggle.apply(button, [e]);
    }
});
});

这里有一个jsfiddle,它可以随心所欲。

重要提示

  • 我单独定义了toggle函数,以便能够重用它
  • 添加了"测试"一词,这样我就可以点击打开菜单了
  • 始终将事件对象传递给toggle函数,因为它需要停止传播以防止无限循环

功能布局如下:

jQuery(function($) {
    "use strict";
    var $menu = $("#headerNav"),
        $dd = $(".dropdownMenu", $menu),
        //Ddefine function for toggling display so we can reuse it
        toggle = function(e) {
            // Stop propagation will prevent the event to 'bubble' up through its parents again
            // In this case it is needed to prevent an eternal loop (well jQuery will return an error at some point but regardless, this is how we prevent it)
            // Normally click events when triggered are called on the direct element under the mouse, and then its parent, and its parent, because triggering one elements effectively triggers all its parents. Since we catch the click event at the highest level already we should prevent this when it is not needed, or when we click the menu itself, the toggle function will be triggered once because it was clicked and another time because at the highest level, document it might be triggered again
            e.stopPropagation();
            if ($dd.hasClass('homeMenuClass')) {
                $dd.hide().removeClass('homeMenuClass');
            } else {
                $dd.show().addClass('homeMenuClass');
            }
        };
    // Simply binds the already made function to the menu click
    $menu.click(toggle);
    // the document is the highest level in the DOM and most events propagate up till here unless stopped before
    $(document).click(function(e) {
        // Here we check if one of the parents of the target or the target itself is #headernav, if it is the function will be triggered by the menu click
        // If #headerNav is not a parent or the target isn't headerNav itself it means that we clicked somewhere outside of it
        if (($(e.target).parents('#headerNav').length === 0 || e.target.id === 'headerNav') && $dd.hasClass('homeMenuClass')) {
            // Here we take the function toggle and apply $menu to it, make $menu `this` in the context of toggle, this isn't really nessacery for this particular case but I think its neater to call the function in the same context as the normal click would have... 
            // e is passed in an array(the brackets make it an array) as the first argument
            // more on that here:http://trephine.org/t/index.php?title=JavaScript_call_and_apply
            toggle.apply($menu, [e]);
        }
    });
});

编辑

将函数更改为使用类和即时隐藏/显示->这是toggle()所做的,但它不区分元素的状态。

您的代码看起来有些奇怪,请尝试以下操作:

$("#headerNav").click(function(e) {
  $(".dropdownMenu").addClass('homeMenuClass').show();
});
$("html").click(function(e) {
  $(".dropDownMenu").addClass('menuGone').hide();
});

不确定为什么要从事件处理程序返回任何内容,以及preventDefault的最后一个()是关于什么的。此外,您真的需要添加类toggle()吗?此外,我已切换到显示/隐藏,而不是切换,因为您在单击外部时总是希望隐藏,在单击菜单时总是显示。

编辑:如果类用于显示/隐藏菜单,你可以(就像我说的)跳过调用切换/显示/隐藏,只使用add/removeClass,就像这样:

$("#headerNav").click(function(e) {
  $(".dropdownMenu").removeClass('menuGone').addClass('homeMenuClass');
});
$("html").click(function(e) {
  $(".dropDownMenu").removeClass('homeMenuClass').addClass('menuGone');
});

第2版:请注意,当单击#headerNav时,除非您执行e.stopPropagation(),否则单击也会弹出到html。如果e.target是#headerNav或#headerNav的子级,您也可以检查您的html单击处理程序。

尝试onblur()js事件。

$("#headerNav").blur(function(e) {
    return $(".dropDownMenu").addClass('menuGone').toggle();
});

尝试removeClass()

$("html").click(function(e) {
  return $(".dropDownMenu").removeClass('homeMenuClass');
});

你尝试过吗:

$(document).click(function(e) {   
return $(".dropDownMenu").addClass('menuGone').toggle(); 
});

顺便说一句,您可以使用.on(),它重新部署了旧的事件处理程序:http://api.jquery.com/on/

这也可能是一个css问题:你的menuGone类应用了吗?