我不认为这是一个重复的问题。我已经尝试了在这个网站上找到的其他一些解决方案,但没有我想要的决心。 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”时,下拉菜单将保持打开状态。 )
答案 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>