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

时间:2016-12-23 17:53:27

标签: javascript jquery html drop-down-menu submenu

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

我想要实现的是,当用户点击打开的下拉菜单之外的任何地方时,打开的菜单将会关闭。

我喜欢javascript代码从w3schools.com运行的方式,它正在寻找我正在寻找的东西,但是我错过了输入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”时,下拉菜单将保持打开状态。 )

1 个答案:

答案 0 :(得分:0)

此解决方案实现了所有需要的组件,并解决了存在的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>