使用mouseup事件时,关闭菜单时出现问题。 当您在下拉菜单的外部单击时,我希望菜单关闭,这样可以正常工作。但是,当我单击列表元素本身时,菜单一旦打开就不会消失。我希望菜单在您单击元素外部时以及在单击列表项时都消失。
代码在这里: http://jsfiddle.net/6132jg9m/2/
var dropDownContent = document.querySelector(".drop-down-content");
var dropDownTrigger = document.querySelector(".drop-down");
dropDownTrigger.onclick = function () {
dropDownTrigger.classList.toggle("active");
document.addEventListener('mouseup', clickedOutside);
};
function clickedOutside(e) {
if (e.target != dropDownContent &&
e.target.parentNode != dropDownContent) {
dropDownTrigger.classList.remove("active");
}
}
答案 0 :(得分:1)
首先,请勿在首次点击事件内增加事件监听。其次,您必须将不单击菜单元素的条件定为要执行的文档单击事件。
这是您的脚本,使用“ matches”方法做了一些修改:
var dropDownTrigger = document.querySelector(".drop-down");
dropDownTrigger.addEventListener('click', function() {
dropDownTrigger.classList.toggle("active");
});
document.addEventListener('mouseup', function() {
if (!dropDownTrigger.matches(':hover')) {
dropDownTrigger.classList.remove("active");
}
});
https://developer.mozilla.org/en-US/docs/Web/API/Element/matches
答案 1 :(得分:0)
您可以使用event.path(数组)查看路径是否包含菜单并停止事件。
对于不支持路径的浏览器,请遍历父级直到到达正文为止,或者在等于目标时停止。
https://developer.mozilla.org/en-US/docs/Web/API/Event/composedPath
答案 2 :(得分:0)
您已经完成了将近99%。您只需要在dropdowntrigger中调用clickOutSide函数即可。
var dropDownContent = document.querySelector(".drop-down-content");
var dropDownTrigger = document.querySelector(".drop-down");
dropDownTrigger.onclick = function () {
dropDownTrigger.classList.toggle("active");
clickedOutside(e); // this line will solve your problem
};
document.addEventListener('mouseup', clickedOutside);
function clickedOutside(e) {
if (e.target != dropDownContent &&
e.target.parentNode != dropDownContent) {
dropDownTrigger.classList.remove("active");
}
}
如果要为菜单项单击添加不同的逻辑,则应编写一个单独的函数。例如
dropDownTrigger.onclick = function () {
dropDownTrigger.classList.toggle("active");
closeMenuDropDown(e); // this line will solve your problem
document.addEventListener('mouseup', clickedOutside);
};
function closeMenuDropDown() {
dropDownTrigger.classList.remove("active");
}
希望它可以解决您的问题。
答案 3 :(得分:0)
“答案是正确的。这确实有效,但是唯一的事情是,当您单击下拉菜单内部时,菜单关闭。任何可能的解决方法?”
根据OP的要求,该演示已进行了如下修改:
为<a>
的第一个.drop-down
锚分配了.trigger
添加了一个条件,只要单击.trigger
(e.target
),它将在菜单上切换.active
。
.contains()
使用.contains()
引用.drop-down
后代标记,并确定是否单击了任何后代标记(e.target
)。
演示中评论的详细信息
// Register click event on document
document.addEventListener('click', function(e) {
// Reference the menu (ddn = .drop-down)
var ddn = document.querySelector('.drop-down');
/*
Check if any tag nested in menu (ddn.contains)
was clicked (e.target)
*/
var trg = ddn.contains(e.target);
// if the clicked tag was .trigger...
if (e.target.matches('.trigger')) {
// ...toggle .active on menu
ddn.classList.toggle('active');
/*
But if the clicked tag was nested within the menu and the
menu isn't .active...
*/
} else if (trg && !ddn.matches('.active')) {
// ...add the class .active on menu.
ddn.classList.add('active');
// Stop event bubbling so it doesn't trigger the ancestor tags
e.stopPropagation();
// Or if any descendant tags were clicked and the menu was .active...
} else if (trg && ddn.matches('.active')) {
// ...just stop event bubbling
e.stopPropagation();
// Otherwise if it was an ancestor tag of menu...
} else if (!trg) {
// ...remove .active from menu
ddn.classList.remove('active');
}
});
body {
margin: 0;
padding: 0;
font-size: 1rem;
}
nav>span {
cursor: pointer;
}
a {
cursor: pointer;
}
ul {
list-style: none;
margin: 0;
padding: 0;
background: #3ab4a6;
}
ul::after {
content: "";
clear: both;
display: block;
}
nav>ul>li {
float: left;
position: relative;
}
a {
display: block;
padding: 15px;
color: #fff;
text-decoration: none;
font-size: 1.2rem;
}
a:hover,
.drop-down:hover {
background: #49505a;
}
.drop-down {
position: relative;
}
.drop-down.active {
background: #49505a;
}
.drop-down.active>.drop-down-content {
display: block;
}
.drop-down.active>a>#arrow {
transform: rotate(180deg);
}
.drop-down-content {
display: none;
position: absolute;
min-width: 250px;
background: #49505a;
}
#arrow {
-webkit-transition: 0.1s;
transition: 0.1s;
}
.drop-down-content a:hover {
background: #2f343b;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Drop-down-menu</title>
<link rel="stylesheet" href="drop-down-menu.css" />
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.4.1/css/all.css" integrity="sha384-5sAR7xN1Nv6T6+dT2mhtzEpVJvfS3NScPQTrOxhwjIuvcA67KV2R5Jz6kr4abQsz" crossorigin="anonymous">
</head>
<body>
<nav>
<ul>
<li><a href="#">Home</a></li>
<li><a href="#">About</a></li>
<li><a href="#">Contact us</a></li>
<li class="drop-down"><a class='trigger'>More <span id="arrow" class="fa fa-angle-down"></span></a>
<ul class="drop-down-content">
<li><a>Drop down1</a></li>
<li><a>Drop down2</a></li>
<li><a>Drop down3</a></li>
<li><a>Drop down4</a></li>
</ul>
</li>
</ul>
</nav>
</body>
</html>