如何实现 `window.onlick = function(event){` 来关闭下拉菜单?

How can I implement `window.onlick = function(event){` to close drop down menu?

我不认为这是一个重复的问题。我已经尝试了在这个网站上找到的其他一些解决方案,但没有找到我想要的解决方案。 How do I detect a click outside an element? 例如使用 event.stopPropagation(); 并且对我来说不能正确地使用多个菜单。

我想要完成的是,当用户单击打开的下拉菜单之外的任何位置时,打开的菜单将关闭。

我喜欢 w3schools.com 中 javascript 代码的运行方式,它可以满足我的需求,但是我缺少输入 window.onclick = function (event){ 以进行调整所需的内容它进入我的代码结构。

这是我放在一起的示例文件,用于突出显示我要实现的内容。

<!DOCTYPE html>
<html>

<head>
<style>

li > ul{display:none;}
.show {display:block;}
.sub-nav ul {
    background: #efefef; 
    background: linear-gradient(top, #efefef 0%, #bbbbbb 100%);  
    background: -moz-linear-gradient(top, #efefef 0%, #bbbbbb 100%); 
    background: -webkit-linear-gradient(top, #efefef 0%,#bbbbbb 100%); 
    box-shadow: 0px 0px 9px rgba(0,0,0,0.15);
    padding: 0 20px;
    border-radius: 0px;  
    list-style: none;
    position: relative;
}
.sub-nav ul:after {content: ""; clear: both; display: block;}
li {float: left;}
.sub-nav ul li:hover {
    background: #4b545f;
    background: linear-gradient(top, #4f5964 0%, #5f6975 40%);
    background: -moz-linear-gradient(top, #4f5964 0%, #5f6975 40%);
    background: -webkit-linear-gradient(top, #4f5964 0%,#5f6975 40%);
}
.sub-nav ul li:hover a {color: #fff;}
.sub-nav ul li a {
    display: block; 
    padding: 20px 40px;
    color: #757575; 
    text-decoration: none;
}
.sub-nav ul ul {
    background: #5f6975; 
    border-radius: 0px; 
    padding: 0;
    position: absolute; 
    top: 100%;
}
.sub-nav ul ul li {
    float: none; 
    border-top: 1px solid #6b727c;
    border-bottom: 1px solid #575f6a;
    position: relative;
}
.sub-nav ul ul li a {padding: 15px 40px; color: #fff;}
.sub-nav ul ul li a:hover {background: #4b545f;}

</style>
</head>

<body>

<!-- START: nav -->
<div class="sub-nav">
                <div class="container">

                    <ul>
                        <li class="active"><a href="#">ROOT 1</a></li>
                        <li><a href="#">ROOT 2</a></li>
                        <li><a href="#">ROOT 3</a></li>
                        <li><a href="#">ROOT 4</a></li>
                        <li><a href="#">ROOT 5</a></li>

                        <li id="drop-one"><a href="#">DROP 1</a>
                            <ul>
                                <li class="has-sub"><a href="#">SUB MENU 1</a></li>
                                <li class="has-sub"><a href="#">SUB MENU 2</a></li>
                                <li class="has-sub"><a href="#">SUB MENU 3</a></li>
                                <li class="has-sub"><a href="#">SUB MENU 4</a></li>
                            </ul>
                        </li>


                        <li id="drop-two"><a>DROP 2</a>
                            <ul>
                                <li class="has-sub"><a href="#">SUB MENU LONG TITLE 1</a></li>
                                <li class="has-sub"><a href="#">SUB MENU LONG TITLE 2</a></li>
                                <li class="has-sub"><a href="#">SUB MENU LONG TITLE 3</a></li>
                            </ul>
                        </li>
                    </ul>

                </div>
</div>
<!-- END: nav -->






</body>
</html>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script>
    jQuery("li:has(ul)").click(function(){
        jQuery("ul",this).toggleClass("show");
    });


window.onclick = function(event) {
    if (!event.target.matches('??????')) {

        var dropdowns = document.getElementsByClassName("??????");
        var i;
        for (i=0; i<dropdowns.length; i++) {
            var openDropdown = dropdowns[i];
            if (openDropdown.classList.contains('show')) {
                openDropdown.classList.remove('show');
            }
        }
    }
}

</script>

尽可能具体,我应该用什么替换“??????”使这个脚本工作。如果html代码需要修改才能使这个脚本工作,请指教,谢谢!

window.onclick = function(event) {
    if (!event.target.matches('??????')) {

        var dropdowns = document.getElementsByClassName("??????");
        var i;
        for (i=0; i<dropdowns.length; i++) {
            var openDropdown = dropdowns[i];
            if (openDropdown.classList.contains('show')) {
                openDropdown.classList.remove('show');
            }
        }
    }
}



更新:2016 年 12 月 27 日 只是为了跟进,我能够提出我认为需要进行的修改以实现所需的内容。

首先我分别添加了li,ul 类 "dropdown" 和"is-open"。

<li class="dropdown"><a href="#">DROP 1</a>
    <ul class="is-open">
        <li><a href="#">SUB MENU 1</a></li>
        <li><a href="#">SUB MENU 2</a></li>
        <li><a href="#">SUB MENU 3</a></li>
        <li><a href="#">SUB MENU 4</a></li>
    </ul>
</li>


<li class="dropdown"><a href="#">DROP 2</a>
    <ul class="is-open">
        <li><a href="#">SUB MENU LONG TITLE 1</a></li>
        <li><a href="#">SUB MENU LONG TITLE 2</a></li>
        <li><a href="#">SUB MENU LONG TITLE 3</a></li>
    </ul>
</li>

其次,我将之前的脚本替换为:

<script>


    // this is the function caller for click into drop down menu
    $(document).ready(function(){
        // this to function call targets the drop down menu by elements
        $("li:has(ul)").click(function(){
            // (IMPORTANT) code to hide existing open drop down menu before displaying new drop down menu 
            $(".is-open").hide();
            // code to toggle menu from drop down ROOT 
            $(this).find(".is-open").toggle();
        });// END: .click
    });// END: .ready

    //this script closes menu when clicked outside of drop down menu.
    $(document).on("click", function(event){
        var $triggerOn = $(".dropdown");
        if($triggerOn !== event.target && !$triggerOn.has(event.target).length){
            $(".is-open").hide();
        }// END: if statement            
    });// END: .on  



</script>

这让我能够实现我想要的,即在下拉菜单外单击并关闭菜单。

我现在只剩下一个问题了,那就是单击 "DROP x" 根级别。菜单将在单击时展开,但在根级别上的第二次单击将不再关闭下拉菜单。有什么解决这个问题的建议吗?

(注意:如果我从脚本中删除 $(".is-open").hide();,它会恢复点击打开和点击关闭功能,但是当点击从 "DROP 1" 到 "DROP 2" 时,下拉菜单将保持开放。)

此解决方案实现了所有需要的组件并解决了存在的 jQuery 脚本错误。

<!DOCTYPE html>
<html>

<head>

<style>

li > ul{display:none;}
.show {display:block;}
.sub-nav ul {
    background: #efefef; 
    background: linear-gradient(top, #efefef 0%, #bbbbbb 100%);  
    background: -moz-linear-gradient(top, #efefef 0%, #bbbbbb 100%); 
    background: -webkit-linear-gradient(top, #efefef 0%,#bbbbbb 100%); 
    box-shadow: 0px 0px 9px rgba(0,0,0,0.15);
    padding: 0 20px;
    border-radius: 0px;  
    list-style: none;
    position: relative;
}
.sub-nav ul:after {content: ""; clear: both; display: block;}
li {float: left;}
.sub-nav ul li:hover {
    background: #4b545f;
    background: linear-gradient(top, #4f5964 0%, #5f6975 40%);
    background: -moz-linear-gradient(top, #4f5964 0%, #5f6975 40%);
    background: -webkit-linear-gradient(top, #4f5964 0%,#5f6975 40%);
}
.sub-nav ul li:hover a {color: #fff;}
.sub-nav ul li a {
    display: block; 
    padding: 20px 40px;
    color: #757575; 
    text-decoration: none;
}
.sub-nav ul ul {
    background: #5f6975; 
    border-radius: 0px; 
    padding: 0;
    position: absolute; 
    top: 100%;
}
.sub-nav ul ul li {
    float: none; 
    border-top: 1px solid #6b727c;
    border-bottom: 1px solid #575f6a;
    position: relative;
}
.sub-nav ul ul li a {padding: 15px 40px; color: #fff;}
.sub-nav ul ul li a:hover {background: #4b545f;}

</style>

</head>

<body>

<!-- START: nav -->
<div class="sub-nav">
                <div class="container">

                    <ul>
                        <li class="active"><a href="#">ROOT 1</a></li>
                        <li><a href="#">ROOT 2</a></li>
                        <li><a href="#">ROOT 3</a></li>
                        <li><a href="#">ROOT 4</a></li>
                        <li><a href="#">ROOT 5</a></li>

                        <li class="dropdown"><a href="#">DROP 1</a>
                            <ul class="is-open">
                                <li><a href="#">SUB MENU 1</a></li>
                                <li><a href="#">SUB MENU 2</a></li>
                                <li><a href="#">SUB MENU 3</a></li>
                                <li><a href="#">SUB MENU 4</a></li>
                            </ul>
                        </li>


                        <li class="dropdown"><a href="#">DROP 2</a>
                            <ul class="is-open">
                                <li><a href="#">SUB MENU LONG TITLE 1</a></li>
                                <li><a href="#">SUB MENU LONG TITLE 2</a></li>
                                <li><a href="#">SUB MENU LONG TITLE 3</a></li>
                            </ul>
                        </li>
                    </ul>

                </div>
</div>
<!-- END: nav -->

</body>
</html>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script>
    // this is the function caller for click into drop down menu
$(document).ready(function(){
  $("li:has(ul)").click(function(){
    if ($(this).find(".is-open").is(":visible")) {
      $(".is-open").hide();
    } else {
      $(".is-open").hide();
      $(this).find(".is-open").toggle();
    }
  });
}); 
    //this script closes menu when clicked outside of drop down menu.
    $(document).on("click", function(event){
        var $triggerOn = $(".dropdown");
        if($triggerOn !== event.target && !$triggerOn.has(event.target).length){
            $(".is-open").hide();
        }// END: if statement            
    });// END: .on  
</script>