通过在Javascript中单击外部关闭下拉列表(教程说明)

时间:2018-05-22 10:42:39

标签: javascript html web

我试图通过w3schools.com上的this教程使用Javascript来实现打开和关闭下拉列表的方法。虽然“显示”下拉列表的功能起作用,但关闭它的功能却没有。此外,除了此代码之外,没有任何解释可以解释为什么应该工作,这使得调试变得困难。

/* When the user clicks on the button, 
toggle between hiding and showing the dropdown content */
function myFunction() {
    document.getElementById("myDropdown").classList.toggle("show");
}

// Close the dropdown menu if the user clicks outside of it
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');
      }
    }
  }
}

因此,我的问题是

1)教程中的代码是否适用于关闭下拉列表的目的。 (ANSWERED)

2)为了清楚我自己和将来遇到相同教程和问题的新手,有人可以澄清这应该如何/为什么会起作用? (未应答)

编辑(我的尝试):

HTML:

<div class="sharedown">     
    <p onclick="shareVis()" class="sharebtn">&nbsp Share</p>
    <div id="mySharedown" class="sharedown-content">
        <a href="#">Self</a>
        <p>User</p><input type="text" name="user-name" placeholder="Share to">
        <a href="#">Community</a>
    </div> 
</div>

JS:

function shareVis() {
    document.getElementById("mySharedown").className = "show";
}

window.onclick = function(event) {
    if (!event.target.matches('sharebtn')) {

        var sharedowns = document.getElementsByClassName("sharedown-content");
        var i;
        for (i = 0; i < sharedowns.length; i++) {
            var openSharedown = sharedowns[i];
            if (openSharedown.classList.contains('show')) {
                openSharedown.classList.remove('show');
            }
        }
    }   
}

CSS:

/* Share dropdown menu */

p.sharebtn {

    color: darkgrey;
    font-family:calibri;
    padding: 0px;
    margin: 0px;
    font-size: 12;
    border: none;
    cursor: pointer;
    display:    inline; 
}

/* Dropdown button on hover & focus */
p.sharebtn:hover, p.sharebtn:focus {
    color: grey;

}

/* The container <div> - needed to position the dropdown content */

.sharedown {
    position: relative;
    display:    inline-block;   

}

/* Dropdown Content (Hidden by Default) */
.sharedown-content {
    display: none;
    position: absolute;
    background-color:   #f1f1f1;
    min-width:  100px;
    box-shadow: 0 2px 4px 1px #C4E3F5;
    z-index:1; /* place dropdown infront of everything else*/
}

.sharedown-content a { 
color: black;
padding: 5px 5px;
text-decoration: none;
display: block;
}

/* Show the dropdown menu (use JS to add this class to the .dropdown-
content container when the user clicks on the dropdown button) */

.show {display: block;
    position: absolute;
    background-color:   #f1f1f1;
    min-width:  100px;
    box-shadow: 0 2px 4px 1px #C4E3F5;
    opacity: 1;
    z-index:1;}

3 个答案:

答案 0 :(得分:3)

问题在于shareVis功能。这里

document.getElementById("mySharedown").className = "show";

您正在将#mySharedown班级名称替换为show。然后在window.onclick

var sharedowns = document.getElementsByClassName("sharedown-content");

由于您已将班级名称替换为sharedowns,因此未获得任何show

<小时/> 您可以将show课程添加到classList

document.getElementById("mySharedown").classList.add("show");

或用sharedown-content show

替换班级名称
document.getElementById("mySharedown").className = "sharedown-content show";

以下工作解决方案:

&#13;
&#13;
function shareVis() {
    //document.getElementById("mySharedown").className = "sharedown-content show";
    document.getElementById("mySharedown").classList.add("show");
}

window.onclick = function(event) {
    if (!event.target.matches('.sharebtn')) {

        var sharedowns = document.getElementsByClassName("sharedown-content");
        var i;
        for (i = 0; i < sharedowns.length; i++) {
            var openSharedown = sharedowns[i];
            if (openSharedown.classList.contains('show')) {
                openSharedown.classList.remove('show');
            }
        }
    }
}

document.getElementById("mySharedown").addEventListener('click',function(event){
    event.stopPropagation();
});
&#13;
#mySharedown{
  display: none;
  border: 1px solid black;
}

#mySharedown.show {
  display: block;
}
&#13;
<div class="sharedown">     
    <p onclick="shareVis()" class="sharebtn">&nbsp Share</p>
    <div id="mySharedown" class="sharedown-content">
        <a href="#">Self</a>
        <p>User</p><input type="text" name="user-name" placeholder="Share to">
        <a href="#">Community</a>
    </div> 
</div>
&#13;
&#13;
&#13;

更新

为防止#mySharedown中的第二次点击隐藏#mySharedown,您应该为click添加另一个#mySharedown事件,并防止它冒泡,就像这样

document.getElementById("mySharedown").addEventListener('click',function(event){
    event.stopPropagation();
});

更新包含在工作解决方案中

答案 1 :(得分:0)

该示例功能齐全,应该可以使用。复制以下代码:

   <!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
.dropbtn {
    background-color: #3498DB;
    color: white;
    padding: 16px;
    font-size: 16px;
    border: none;
    cursor: pointer;
}

.dropbtn:hover, .dropbtn:focus {
    background-color: #2980B9;
}

.dropdown {
    position: relative;
    display: inline-block;
}

.dropdown-content {
    display: none;
    position: absolute;
    background-color: #f1f1f1;
    min-width: 160px;
    overflow: auto;
    box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
    z-index: 1;
}

.dropdown-content a {
    color: black;
    padding: 12px 16px;
    text-decoration: none;
    display: block;
}

.dropdown a:hover {background-color: #ddd}

.show {display:block;}
</style>
</head>
<body>

<h2>Clickable Dropdown</h2>
<p>Click on the button to open the dropdown menu.</p>

<div class="dropdown">
<button onclick="myFunction()" class="dropbtn">Dropdown</button>
  <div id="myDropdown" class="dropdown-content">
    <a href="#home">Home</a>
    <a href="#about">About</a>
    <a href="#contact">Contact</a>
  </div>
</div>

<script>
/* When the user clicks on the button, 
toggle between hiding and showing the dropdown content */
function myFunction() {
    document.getElementById("myDropdown").classList.toggle("show");
}

// Close the dropdown if the user clicks outside of it
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');
      }
    }
  }
}
</script>

</body>
</html>

答案 2 :(得分:0)

这里我留下了另一个“简短”示例,该示例是我在自己的代码中实现的,但很容易理解。

.tw-hidden 是一个类“显示:无”

window.onclick = function(event) {
        let customDropdownsEl = document.querySelectorAll(".custom-dropdown");
        let liContainerEl = event.target.querySelector(".custom-dropdown");
    
        customDropdownsEl.forEach(el => el.parentNode !== event.target && !el.classList.contains("tw-hidden") && el.classList.add("tw-hidden"));
        event.target.matches('.custom-dropdown-container') && liContainerEl.classList.toggle("tw-hidden");
}