简体   繁体   English

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

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

Right now my I click #headerNav and menu drops down as expected but when I click any where outside of the menu it has no effect. 现在我点击#headerNav并按预期的方式下拉菜单但是当我点击菜单外的任何地方时它没有任何效果。

Where am I going wrong? 我哪里错了?

My HTML: 我的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>

My JS: 我的JS:

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

CSS: 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;
}

I have looked at similar questions and tried solutions but none seem to work. 我看过类似的问题并尝试过解决方案,但似乎都没有效果。 Kind regards 亲切的问候

Update: (This is working 100% the way I want it to but for some reason it feels like I'm going about things the wrong way. eg the addClass('homeMenuClass') line.. Slightly confused about the toggle variable function. 更新:(这是按照我想要的方式100%工作,但由于某种原因,我觉得我的方式是错误的。例如addClass('homeMenuClass')行..对切换变量函数稍微有点困惑。

$(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]);
    }
});

});

Your code looks somewhat weird, try this: 你的代码看起来有些奇怪,试试这个:

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

Unsure why you were returning anything from the event handlers and what that last () with preventDefault was about. 不确定为什么要从事件处理程序返回任何内容以及与preventDefault有关的last()。 Also, do you really need to add classes and toggle()? 另外,你真的需要添加类 toggle()吗? Also, I've switched to show/hide instead of toggle as you'll always want to hide when clicking outside and always show when clicking the menu. 此外,我已切换到显示/隐藏而非切换,因为您在外部单击时始终要隐藏,并且在单击菜单时始终显示。

Edit: If the classes are used to show/hide the menu you can (like I said) skip the call to toggle/show/hide and just use add/removeClass, like this: 编辑:如果这些类用于显示/隐藏菜单,你可以(就像我说的那样)跳过调用toggle / show / hide并使用add / removeClass,如下所示:

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

Edit2: Note that when clicking #headerNav the click will bubble up to html as well unless you do e.stopPropagation(). 编辑2:请注意,单击#headerNav时,除非您执行e.stopPropagation(),否则点击将冒泡到html。 You could also check in your html click handler if e.target was #headerNav or a child of #headerNav. 如果e.target是#headerNav或者#headerNav的孩子,你也可以检查你的html点击处理程序。

Here is a jsfiddle that does what you want. 这是一个做你想要的jsfiddle

Important notes 重要笔记

  • I defined the toggle function seperately to be able to reuse it. 我单独定义了切换功能以便能够重复使用它。
  • Added the word 'Test' so I had something to click to open the menu 添加了“测试”一词,所以我点击了一下打开菜单
  • Always pass the event object to the toggle function since it needs to stop propagation to prevent an infinite loop. 始终将事件对象传递给toggle函数,因为它需要停止传播以防止无限循环。

The function is layed out as following: 功能如下:

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

});

Edit 编辑

Changed the function to use your classes and an instant hide/show -> this is what toggle() does but it's indescriminate of what state your element is in. 更改了使用你的类的功能和即时隐藏/显示 - >这就是toggle()所做的事情,但是它不确定你的元素处于什么状态。

Try the onblur() js event. 试试onblur()js事件。

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

try removeClass() 尝试removeClass()

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

Did you try : 你试过了吗 :

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

Btw, you could use .on() , which remplace old event handlers : http://api.jquery.com/on/ 顺便说一句,你可以使用.on() ,它重新设置旧的事件处理程序: http ://api.jquery.com/on/

It may also be a css problem : is your menuGone class applied ? 它也可能是一个CSS问题:你的menuGone类是应用的吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM