点击页面关闭下拉菜单

时间:2017-07-01 20:35:57

标签: javascript

我已经浏览了类似的帖子,似乎已经遇到了关于这个实现的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>

提前致谢,祝你有个美好的一天!

3 个答案:

答案 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()

&#13;
&#13;
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;
&#13;
&#13;

答案 2 :(得分:0)

我添加了两个onclick事件。 window.onclick识别出点击不在按钮上。

&#13;
&#13;
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;
&#13;
&#13;