我已经浏览了类似的帖子,似乎已经遇到了关于这个实现的javascript如何工作的障碍。我有一个带有过滤器的下拉列表,我单击一个按钮来启动下拉列表。这很好用。但是,似乎解除此下拉列表的唯一方法是单击原始按钮。当我点击屏幕上除了下拉菜单之外的任何其他地方时,我试图解雇。我不确定我接近这个方式是否是javascript的怪癖,但是下面的代码列出了我的方法,并且在概念层面上我认为这应该可以正常工作:
代码:
function myFunction() {
document.getElementById("myDropdown").classList.toggle("show");
}
window.onclick = function(event) {
if (!event.target.matches('.dropbtn')) {
var dropdowns = document.getElementsByClassName("dropdown-content");
var i;
for (i = 0; i < dropdowns.length; i++) {
var openDropdown = dropdowns[i];
if (openDropdown.classList.contains('show')) {
openDropdown.classList.remove('show');
}
}
}
}
function filterFunction() {
var input, filter, ul, li, a, i;
input = document.getElementById("myInput");
filter = input.value.toUpperCase();
div = document.getElementById("myDropdown");
a = div.getElementsByTagName("a");
for (i = 0; i < a.length; i++) {
if (a[i].innerHTML.toUpperCase().indexOf(filter) > -1) {
a[i].style.display = "";
} else {
a[i].style.display = "none";
}
}
}
<div class="dropdown">
<button onclick="myFunction()" class="dropbtn"><img src="bread.png" height="50" width="50" style="vertical-align:middle" align="left"><a>Testing</a></button>
<div id="myDropdown" class="dropdown-content">
<input type="text" placeholder="Search.." id="myInput" onkeyup="filterFunction()">
<a> Dropdown Content 1 </a>
<a> Dropdown Content 2 </a>
<a> Dropdown Content 3 </a>
</div>
</div>
提前致谢,祝你有个美好的一天!
答案 0 :(得分:1)
我最近写了一篇blog post - Evolution of Drop Down Menus and Exiting Them关于这个针对整个页面点击的技术,介绍了一个留在后台的人造面具。
我在这里只为事件监听器使用jQuery,但主要概念是掩码。这也是关闭和开放背后的逻辑:
click() {
if (other_dropdowns_open) {
close_others;
open_current;
} else {
if (current_dropdown_open)
close_current;
else
open_current;
}
}
代码在这里:
$(function () {
$(".dd-trigger").click(function (e) {
e.preventDefault();
$("body").addClass("dd-open");
$(this).closest(".dd").toggleClass("open");
});
$(".dd-mask").click(function () {
$("body").removeClass("dd-open");
$(".open").removeClass("open");
});
});
.dd {display: inline-block; position: relative;}
.dd .dd-trigger {display: block; text-decoration: none; border: 1px solid #ccf; padding: 5px; border-radius: 5px; color: #000; min-width: 100px;}
.dd .dd-trigger img {margin-top: 5px; float: right;}
.dd .dd-menu,
.dd .dd-menu li {margin: 0; padding: 0; list-style: none;}
.dd .dd-menu {display: none; position: absolute; z-index: 2; background-color: #f5f5f5; border: 1px solid #ccf; left: 0; right: 0; margin-top: -3px; border-top: 0;}
.dd .dd-menu a {display: block; text-decoration: none; line-height: 1; padding: 5px; color: #000; margin: 2px 0;}
.dd .dd-menu a:hover {background-color: #fff;}
.dd.open .dd-menu {display: block;}
.dd-mask {position: fixed; z-index: 1; left: 0; top: 0; bottom: 0; right: 0; display: none;}
.dd-open .dd-mask {display: block;}
input {width: 90%; margin: 5px; border: 1px solid #ccc; padding: 3px 5px;}
li:first-child input {margin-bottom: 0;}
<script src="https://code.jquery.com/jquery-2.2.4.js"></script>
<div class="dd-mask"></div>
<div class="dd">
<a href="#" class="dd-trigger">
Account
<img src="https://www.mydemenageur.com/images/caret_open.png" alt="Drop Down" />
</a>
<ul class="dd-menu">
<li><a href="">Profile</a></li>
<li><a href="">Settings</a></li>
<li><a href="">Logout</a></li>
</ul>
</div>
<div class="dd">
<a href="#" class="dd-trigger">
Help
<img src="https://www.mydemenageur.com/images/caret_open.png" alt="Drop Down" />
</a>
<ul class="dd-menu">
<li><a>Empty Clicker</a></li>
<li><a href="">Questions</a></li>
<li><a href="">Support</a></li>
</ul>
</div>
<div class="dd">
<a href="#" class="dd-trigger">
Search
<img src="https://www.mydemenageur.com/images/caret_open.png" alt="Drop Down" />
</a>
<ul class="dd-menu">
<li><label><input type="search" /></label></li>
<li><input type="submit" value="Search" /></li>
</ul>
</div>
注意:我只使用jQuery来添加或删除类。请参阅下文,了解如何使用纯JavaScript执行此操作:
element.classList.add("className"); // Adding
element.classList.remove("className"); // Removing
快速查看原始帖子,您可能能够理解如何实现CSS。
加分:我的文章解释了如何避免搜索按钮点击和解除菜单问题!查看上面的演示以查看它的实际效果,并查看我的文章以了解它。
答案 1 :(得分:1)
您遇到的问题是事件冒泡。当您单击按钮时,事件会冒泡到window
对象,然后关闭菜单的函数会运行。
您可以拨打event.stopPropagation()
中的myFunction()
来阻止此操作。
我还更改了window.onclick
函数以使用document.querySelectorAll()
,因此它只是循环显示的下拉列表,而不是在循环中调用classList.contains()
。
function myFunction(event) {
document.getElementById("myDropdown").classList.toggle("show");
event.stopPropagation();
}
window.onclick = function(event) {
if (!event.target.matches('.dropbtn')) {
var dropdowns = document.querySelectorAll(".dropdown-content.show");
for (var i = 0; i < dropdowns.length; i++) {
var openDropdown = dropdowns[i];
openDropdown.classList.remove('show');
}
}
}
function filterFunction() {
var input, filter, ul, li, a, i;
input = document.getElementById("myInput");
filter = input.value.toUpperCase();
div = document.getElementById("myDropdown");
a = div.getElementsByTagName("a");
for (i = 0; i < a.length; i++) {
if (a[i].innerHTML.toUpperCase().indexOf(filter) > -1) {
a[i].style.display = "";
} else {
a[i].style.display = "none";
}
}
}
&#13;
.dropdown-content {
display: none;
}
.dropdown-content.show {
display: block;
}
&#13;
<div class="dropdown">
<button onclick="myFunction(event)" class="dropbtn"><img src="bread.png" height="50" width="50" style="vertical-align:middle" align="left"><a>Testing</a></button>
<div id="myDropdown" class="dropdown-content">
<input type="text" placeholder="Search.." id="myInput" onkeyup="filterFunction()">
<a> Dropdown Content 1 </a>
<a> Dropdown Content 2 </a>
<a> Dropdown Content 3 </a>
</div>
</div>
&#13;
答案 2 :(得分:0)
我添加了两个onclick事件。 window.onclick
识别出点击不在按钮上。
var button = document.getElementById("myDropdown");
window.onclick = function(event) {
if (event.target.tagName !== "BUTTON") {
if (button.style.display != "none") {
button.style.display = "none";
}
}
}
function myFunction() {
window.click = false;
if (button.style.display != "none") {
button.style.display = "none";
} else {
button.style.display = "";
}
}
&#13;
<div class="dropdown">
<button onclick="myFunction()" class="dropbtn">
<img src="bread.png" height="50" width="50" style="vertical-align:middle" align="left">
<a>Testing</a></button>
<div id="myDropdown" class="dropdown-content">
<input type="text" placeholder="Search.." id="myInput" onkeyup="filterFunction()">
<a> Dropdown Content 1 </a>
<a> Dropdown Content 2 </a>
<a> Dropdown Content 3 </a>
</div>
</div>
&#13;