如何使用Javascript关闭外部点击css下拉菜单?

时间:2021-05-16 14:30:29

I want to use pure javascript (not jquery) to close a pure css drop-down menu I have created when clicking outside of the menu. How can I do this?

我想使用纯javascript(而不是jquery)来关闭我在单击菜单外部时创建的纯css下拉菜单。我怎样才能做到这一点?

HTML:

<ul>
    <div class="submenu">
        <ul></ul>
    </div>
    <div class="submenu">
        <ul></ul>
    </div>
</ul>

That's the basic structure of my HTML. I want to close the submenu if clicking outside of the submenu. Any way to do so with pure javascript? So far I've tried this:

这是我的HTML的基本结构。如果单击子菜单外部,我想关闭子菜单。使用纯javascript的任何方式吗?到目前为止,我试过这个:

Javascript:

        <script>
            document.onclick = closeMenu();
            function closeMenu() {
                document.getElementsByClassName("submenu").style.display = 'none';
            }
        </script>

This doesn't seem to work. Any ideas?

这似乎不起作用。有任何想法吗?

1 个解决方案

#1


A few changes: you are assigning the onclick incorrectly, it should be a reference to your function, not the result of calling your function:

一些变化:你正在分配onclick错误,它应该是你的函数的引用,而不是调用你的函数的结果:

 document.onclick = closeMenu;

Second, you need to use event delegation to determine if the clicked element is a descendent of your submenu div. Something like this function should work for figuring out if the event target node is a child of submenu:

其次,您需要使用事件委派来确定被点击的元素是否是子菜单div的后代。类似这个函数的东西应该用于确定事件目标节点是否是子菜单的子节点:

function parentIsSubmenu(child) {
     var node = child.parentNode;
     while (node != null) {
         if ((node.className || '').indexOf('submenu') > -1) {
             return true;
         }
         node = node.parentNode;
     }
     return false;
}

Alter your closeMenu function to check if the clicked element is a child of submenu, if not, loop through each submenu item and set display to none (what you currently have would not work).

改变你的closeMenu函数来检查被点击的元素是否是子菜单的子元素,如果没有,循环遍历每个子菜单项并将display设置为none(你当前拥有的东西不起作用)。

function closeMenu(event) {
    if(!parentIsSubmenu(event.target)) {
        var submenus = document.getElementsByClassName("submenu");
        for(var i = 0; i < submenus.length; i++) {
            submenus[i].style.display = 'none';
        }
    }
}

Here is a working example: https://jsfiddle.net/m2muz5en/

这是一个有效的例子:https://jsfiddle.net/m2muz5en/

#1


A few changes: you are assigning the onclick incorrectly, it should be a reference to your function, not the result of calling your function:

一些变化:你正在分配onclick错误,它应该是你的函数的引用,而不是调用你的函数的结果:

 document.onclick = closeMenu;

Second, you need to use event delegation to determine if the clicked element is a descendent of your submenu div. Something like this function should work for figuring out if the event target node is a child of submenu:

其次,您需要使用事件委派来确定被点击的元素是否是子菜单div的后代。类似这个函数的东西应该用于确定事件目标节点是否是子菜单的子节点:

function parentIsSubmenu(child) {
     var node = child.parentNode;
     while (node != null) {
         if ((node.className || '').indexOf('submenu') > -1) {
             return true;
         }
         node = node.parentNode;
     }
     return false;
}

Alter your closeMenu function to check if the clicked element is a child of submenu, if not, loop through each submenu item and set display to none (what you currently have would not work).

改变你的closeMenu函数来检查被点击的元素是否是子菜单的子元素,如果没有,循环遍历每个子菜单项并将display设置为none(你当前拥有的东西不起作用)。

function closeMenu(event) {
    if(!parentIsSubmenu(event.target)) {
        var submenus = document.getElementsByClassName("submenu");
        for(var i = 0; i < submenus.length; i++) {
            submenus[i].style.display = 'none';
        }
    }
}

Here is a working example: https://jsfiddle.net/m2muz5en/

这是一个有效的例子:https://jsfiddle.net/m2muz5en/