单击菜单外的菜单关闭不起作用 - buttonevent.matches 如果不是函数

Click menu close outside of menu not working - buttonevent.matches if not a function

单击菜单按钮外部时应该关闭的下拉菜单不起作用。我以前遇到过这个问题,但问题再次出现,无法解决。帮助将不胜感激。我不确定为什么代码不起作用,所以澄清一下会有帮助。

let btnn = document.getElementById("btn");
btnn.addEventListener('click', function() {
  let dropdown = document.getElementById('dropdown');
  dropdown.classList.toggle("visible");
})

window.onclick = function(event){
    if (!event.target.matches('#btn')) {
        let dropd = document.getElementById('dropdown');
        dropd.classList.remove("visible");
    } 
}
body {
    height: 100vh;
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

.logo {
    display: block;
    text-align: left;
    background: red;
    height: 10vh;
}

.logo #logo {
    display: inline;
    line-height: 10vh;
    font-size: 3em;
    margin-left: 0.8em;
    
}

button#btn {
    display: inline;
    float: right;
    margin-right: 2em;
    margin-top: 0;
    margin-bottom: 0;
    border: none;
    background-color: red;
    padding: 0;
}

nav {
    display: block;
    background-color: black;
    width: 100vw;
}

nav ul {
    display: none;
    list-style-type: none;
    margin: 0;
    padding-left: 0;
}

nav ul li {
    text-align: center; 
}

.link {
    display: block;
    color: white;
    font-size: 2.4em;
    background-color: blue;
    text-decoration: none;
    width: 100vw;
    height: 7vh;
    line-height: 7vh;
    border-bottom: 2px solid black;
    text-align: center;
}

.visible {
    display: block;
}

.fa-bars:before, .fa-navicon:before {
    content: "\f0c9";
    font-size: 50px;
    line-height: 10vh;
}

@media only screen and (min-width: 480px) { 
    
    .fa-bars:before, .fa-navicon:before {
        font-size: 35px;
    }

    /* #dropdown {
        display: block;
    } */

}
  
  @media only screen and (min-width: 600px) {

    .fa-bars:before, .fa-navicon:before {
        font-size: 30px;
    }
    
}
<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="width=device-width">
    <!-- <meta http-equiv="content-type" content="text/html; charset=UTF-8" /> -->
    <script
  src="https://code.jquery.com/jquery-3.6.0.js"
  integrity="sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk="
  crossorigin="anonymous"></script>
    <script src="https://kit.fontawesome.com/36947df53d.js" crossorigin="anonymous"></script>
    <link rel="stylesheet" type="text/css" href="style.css" />
  </head>
  <body>
  <div class="logo">
    <p id="logo">Logo</p>
    <button id="btn"><i class="fa-solid fa-bars"></i></button>
  </div>
   <nav>
     <ul id="dropdown">
       <li><a href="#" class="link">Link 1</a></li>
       <li><a href="#" class="link">Link 2</a></li>
       <li><a href="#" class="link">Link 3</a></li>
     </ul>
   </nav>
    <script src="script.js"></script>
  </body>
</html>

您可以使用 document.body.addEventListener('click', fn, true);。你的 js 文件应该是这样的 maybe

let btnn = document.getElementById("btn");
btnn.addEventListener('click', function() {
  let dropdown = document.getElementById('dropdown');
  dropdown.classList.toggle("visible");
})

document.body.addEventListener("click", () => {
    let dropd = document.getElementById('dropdown');
    dropd.classList.remove("visible");
}, true); 

让我更好地重组您的 javascript。它会解决你的问题,我认为代码也很精确。

document.querySelector("body").addEventListener("click", function(event){  
  let dropd = document.querySelector('#dropdown');
  if (!event.target.parentNode.matches('#btn')) {    
    dropd.classList.remove("visible");
  } else {
    dropd.classList.toggle("visible");
  }
});

在您之前的代码中,我相信您的按钮点击被 window 点击覆盖了。在这里,我单击正文并简单地匹配按钮 ID。如果匹配,则我将进行切换,否则,我将删除 class.

*** 我用过parentNode。如果您想知道我为什么使用它,您可以简单地通过控制台日志查看按钮点击发生的位置。你会看到点击是在按钮内获取图标。这就是为什么我用图标父级来检查点击是否发生在我想要的地方。