单击外部汉堡菜单以使用 javascript 关闭

click outside burger menu to close using javascript

我一直在制作可在桌面上运行的汉堡菜单,通过事件侦听器打开和关闭。

它工作正常,但后来我想这样做,如果在汉堡菜单外单击使用,它也会关闭菜单。

我发现了一些 java 脚本,它使用一些逻辑来说明如果不是导航则关闭菜单。当您在菜单外单击时它可以工作,但问题是切换停止关闭菜单。

我将我的代码分成两部分。 第一个代码块是使用切换的代码。 第二个块是我用来尝试使菜单外的点击起作用的代码。

我想我已经盯着这个看很久了,似乎找不到解决办法。

在此先感谢您的帮助。

<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title></title>
  </head>
  <body>

    <style>

a{
  color: #fff;
}

.ic-burger{
  width: 50px;
  height: 50px;
  background: #000;
  display: block;
  position: relative;
  z-index: 10;

}


.ic-nav ul {
    list-style: none;
    padding-left: 0px;
    display: flex;
    flex-direction: column;

    right: 0px;
    top: 0px;
    height: 100%;
    position: fixed;
    z-index: 5;
    overflow: auto;
    margin: 0px;
    padding-left: 20px;
    padding-right: 20px;

    }


html.ic-show .ic-nav:before{
  content: '';
  position: absolute;
top: 0;
left: auto;
right: 0;
bottom: 0;
    background-color: rgba(18,18,18,0.7);
z-index: 1;
width: 100%
}


.ic-second-level{
  opacity: 0;
  visibility: hidden;
  transition: all 200ms linear;
  padding: 0px;
  padding-top: 100px;
    background: #1e1e1e;

}

html.ic-show .ic-second-level{
  opacity: 1;
  visibility: visible;


}

    </style>

    <nav class="ic-nav">
  <!-- <div class="ic-burger-bkg"> -->
      <ul class="ic-burger-container">
        <li>
          <a href="javascript:void(0);" class="ic-burger" aria-expanded="false" aria-controls="menu" id="burger-icon">
            <div class="nav-icon">
            Burger <br>toggle
            </div>
          </a>
          <!-- ############ -->
          <ul class="ic-second-level" role="region" id="menu" aria-labeledby="burger-icon">
            <li class="top-li">
              <a href="/about/" class="">About</a>
            </li>
            <li class="top-li">
              <a href="/news/" class="">News</a>
            </li>

            <li class="top-li">
              <a href="/team/" class="">Team</a>
            </li>
            <li class="top-li">
              <a href="/contact/" class="">Contact</a>
            </li>
          </ul>
          <!-- ############ -->
        </li>
      </ul>
  <!-- </div> -->
    </nav>



  </body>


<script>
var documentElement = document.querySelector("html");
var sidebarIsOpen = () => documentElement.classList.contains("ic-show");


var openSidebar = () => {

documentElement.classList.add("ic-show");
};

var closeSidebar = () => {
documentElement.classList.remove("ic-show");
};


document.querySelector('.ic-burger').addEventListener("click", function() {
sidebarIsOpen() ? closeSidebar() : openSidebar();
  });




</script>



</html>

这是第二段代码,我无法与第一段友好地玩。

  let sidebar = document.querySelector(".ic-second-level");

  document.addEventListener("mouseup", function(event){
    // If the event didn't originate from the open button or the sidebar, close it
    if(event.target !== sidebar && event.target !== openSidebar){
      closeSidebar();
    }
  });

这是我用来帮助我的两个来源 https://dev.to/tongrhj/the-mistake-developers-make-when-coding-a-hamburger-menu-1deg

我正在使用 event delegation 检查您是否单击了“ic-nav”元素然后将其关闭。像魅力一样工作。

document.addEventListener('click',function(e){
    if(e.target && e.target.classList == 'ic-nav'){
        sidebarIsOpen() ? closeSidebar() : openSidebar();
     }
 });

var documentElement = document.querySelector("html");
var sidebarIsOpen = () => documentElement.classList.contains("ic-show");


var openSidebar = () => {

documentElement.classList.add("ic-show");
};

var closeSidebar = () => {
documentElement.classList.remove("ic-show");
};


document.querySelector('.ic-burger').addEventListener("click", function() {
    sidebarIsOpen() ? closeSidebar() : openSidebar();
});

 document.addEventListener('click',function(e){
    if(e.target && e.target.classList == 'ic-nav'){
        sidebarIsOpen() ? closeSidebar() : openSidebar();
     }
 });
a{
  color: #fff;
}

.ic-burger{
  width: 50px;
  height: 50px;
  background: #000;
  display: block;
  position: relative;
  z-index: 10;

}


.ic-nav ul {
    list-style: none;
    padding-left: 0px;
    display: flex;
    flex-direction: column;

    right: 0px;
    top: 0px;
    height: 100%;
    position: fixed;
    z-index: 5;
    overflow: auto;
    margin: 0px;
    padding-left: 20px;
    padding-right: 20px;

    }


html.ic-show .ic-nav:before{
  content: '';
  position: absolute;
top: 0;
left: auto;
right: 0;
bottom: 0;
    background-color: rgba(18,18,18,0.7);
z-index: 1;
width: 100%
}


.ic-second-level{
  opacity: 0;
  visibility: hidden;
  transition: all 200ms linear;
  padding: 0px;
  padding-top: 100px;
    background: #1e1e1e;

}

html.ic-show .ic-second-level{
  opacity: 1;
  visibility: visible;


}
<nav class="ic-nav">
  <!-- <div class="ic-burger-bkg"> -->
      <ul class="ic-burger-container">
        <li>
          <a href="javascript:void(0);" class="ic-burger" aria-expanded="false" aria-controls="menu" id="burger-icon">
            <div class="nav-icon">
            Burger <br>toggle
            </div>
          </a>
          <!-- ############ -->
          <ul class="ic-second-level" role="region" id="menu" aria-labeledby="burger-icon">
            <li class="top-li">
              <a href="/about/" class="">About</a>
            </li>
            <li class="top-li">
              <a href="/news/" class="">News</a>
            </li>

            <li class="top-li">
              <a href="/team/" class="">Team</a>
            </li>
            <li class="top-li">
              <a href="/contact/" class="">Contact</a>
            </li>
          </ul>
          <!-- ############ -->
        </li>
      </ul>
  <!-- </div> -->
    </nav>