如何实现 `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>
我不认为这是一个重复的问题。我已经尝试了在这个网站上找到的其他一些解决方案,但没有找到我想要的解决方案。 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>