简体   繁体   English

单击暗区时如何关闭侧边菜单?

[英]How to close side menu when the dark area is clicked?

I built a simple side navigation.我构建了一个简单的侧面导航。 If you run the snippet and resize the window to smaller size you'll see a red square.如果您运行代码段并将窗口调整为较小的尺寸,您将看到一个红色方块。 If you click on it, the menu opens.如果单击它,菜单将打开。

The menu opens fine, however I'd like to close the menu when I click the dark area, not the X. I tried adding a "click" eventListener to the body itself and remove the "is-open" class but didn't work.菜单打开得很好,但是当我点击黑暗区域而不是 X 时我想关闭菜单。我尝试向主体本身添加一个“点击”事件监听器并删除“is-open”类,但没有工作。 I spent several hours thinking what could be the problem and finally decided to post here and ask for your suggestion.我花了几个小时思考可能是什么问题,最后决定在这里发帖并征求您的建议。

 "use strict"; const menuToggle = document.querySelector(".menu-toggle"); const menuClose = document.querySelector(".menu-close"); const nav = menuToggle.parentElement; menuToggle.addEventListener("click", event => { event.preventDefault(); nav.classList.add("is-open"); document.body.style.backgroundColor = "rgba(0,0,0,0.5)"; }); menuClose.addEventListener("click", event => { event.preventDefault(); menuToggle.nextElementSibling.style.width = null; document.body.style.backgroundColor = null; nav.classList.remove("is-open"); });
 :root { box-sizing: border-box; } *, *::before, *::after { box-sizing: inherit; } body { margin: 0; padding: 0; } .menu-toggle { width: 40px; height: 40px; border: 1px solid red; cursor: pointer; } .menu-container { position: absolute; background: lightskyblue; height: 100vh; width: 0; transition: width 0.4s ease-in-out; top: 0; left: 0; overflow: auto; z-index: 1; } .menu-close { position: absolute; right: 1em; } .nav-menu { list-style: none; padding-left: 0; margin: 50px 0 0 0; } .nav-menu > li + li { border-top: 1px solid #fff; } .nav-menu > li > a { display: block; color: #000; padding: 0.8em 1em; font-size: 1.1rem; text-decoration: none; text-transform: uppercase; } .nav.is-open .menu-container { width: 200px; } .menu-close::before { content: "\\00d7"; font-size: 2.6rem; } /*@media screen and (min-width: 37.5em) {*/ @media screen and (min-width: 40.5em) { body { background: #fff !important; } .menu-toggle { display: none; } .nav.is-open .menu-container { width: auto; height: auto; } .menu-container { position: initial; height: auto; width: auto; overflow: hidden; } .menu-close { display: none; } .nav-menu { display: flex; position: static; justify-content: center; margin: 0; } .nav-menu > li { margin-left: 1em; } .nav-menu > li + li { border-top: initial; } }
 <!DOCTYPE html> <html lang="en-US"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="hamburgerside.css"> <title>Hamburger Menu Side</title> </head> <body> <nav class="nav"> <div class="menu-toggle"> <span class="menu-toggle__linecenter"></span> </div> <div class="menu-container"> <span class="menu-close"></span> <ul class="nav-menu"> <li><a href="#">Home</a></li> <li><a href="#">Menu Item 1</a></li> <li><a href="#">Menu Item 2</a></li> <li><a href="#">Menu Item 3</a></li> </ul> </div> </nav> <main> <p> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusamus accusantium aliquid consequatur facere illum incidunt magnam magni maiores nam neque numquam omnis perferendis porro quae quibusdam, quos sed tenetur ullam. </p> </main> <script src="hamburgerside.js"></script> </body> </html>

So if I understand correctly what you are trying to do, you will need to use document rather than body for the click event.因此,如果我正确理解您要执行的操作,您将需要使用document而不是body来处理点击事件。 You will also need to use event.stopImmediatePropagation() rather than event.preventDefault() which will allow the first click but not the second.您还需要使用event.stopImmediatePropagation()而不是event.preventDefault()这将允许第一次点击但不允许第二次点击。 Also in the condition you would need to only run the click event if anywhere but the menu is clicked.同样在这种情况下,您只需要在单击菜单之外的任何地方运行 click 事件。

NOTE: I had to remove your media query as it was preventing the toggle-menu from being displayed.注意:我不得不删除您的媒体查询,因为它阻止了切换菜单的显示。

 "use strict"; const menuToggle = document.querySelector(".menu-toggle"); const menuClose = document.querySelector(".menu-close"); const nav = menuToggle.parentElement; menuToggle.addEventListener("click", event => { event.stopImmediatePropagation(); nav.classList.add("is-open"); document.body.style.backgroundColor = "rgba(0,0,0,.5)"; }); document.addEventListener("click", event => { if (nav.classList.contains("is-open") && !event.target.classList.contains("nav-menu")) { menuToggle.nextElementSibling.style.width = null; document.body.style.backgroundColor = "#fff"; nav.classList.remove("is-open"); } });
 :root { box-sizing: border-box; } *, *::before, *::after { box-sizing: inherit; } body { margin: 0; padding: 0; } .menu-toggle { width: 40px; height: 40px; border: 1px solid red; cursor: pointer; } .menu-container { position: absolute; background: lightskyblue; height: 100vh; width: 0; transition: width 0.4s ease-in-out; top: 0; left: 0; overflow: auto; z-index: 1; } .menu-close { position: absolute; right: 1em; } .nav-menu { list-style: none; padding-left: 0; margin: 50px 0 0 0; } .nav-menu > li + li { border-top: 1px solid #fff; } .nav-menu > li > a { display: block; color: #000; padding: 0.8em 1em; font-size: 1.1rem; text-decoration: none; text-transform: uppercase; } .nav.is-open .menu-container { width: 200px; } .menu-close::before { content: "\\00d7"; font-size: 2.6rem; } }
 <nav class="nav"> <div class="menu-toggle"> <span class="menu-toggle__linecenter"></span> </div> <div class="menu-container"> <span class="menu-close"></span> <ul class="nav-menu"> <li><a href="#">Home</a></li> <li><a href="#">Menu Item 1</a></li> <li><a href="#">Menu Item 2</a></li> <li><a href="#">Menu Item 3</a></li> </ul> </div> </nav> <main> <p> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusamus accusantium aliquid consequatur facere illum incidunt magnam magni maiores nam neque numquam omnis perferendis porro quae quibusdam, quos sed tenetur ullam. </p> </main>

Here is what you want, I added a new div next to the menu with a class hidden and for the script when the event.target is equal to that div or the close button then will fire the function.这就是你想要的,我在菜单旁边添加了一个hidden类的新 div,当event.target等于该 div 或关闭按钮时,脚本将触发该函数。 check it out and let me know if you have any questions.检查一下,如果您有任何问题,请告诉我。

 const menuToggle = document.querySelector(".menu-toggle"); const menuClose = document.querySelector(".menu-close"); const menuActive = document.querySelector(".menu_active"); const nav = menuToggle.parentElement; const log = console.log; const app = { init: () => { app.menuToggle(); }, menuToggle: () => { menuToggle.addEventListener("click", event => { event.preventDefault(); nav.classList.add("is-open"); menuActive.classList.remove('hidden'); app.closeMenu(); }); log('working') }, closeMenu: () => { if (nav.classList.contains('is-open')) { document.addEventListener("click", event => { event.preventDefault(); let closeMenu = event.target.className; if (closeMenu === 'menu_active' || closeMenu === 'menu-close') { //log(event.target.className) menuToggle.nextElementSibling.style.width = null; menuActive.classList.add('hidden'); nav.classList.remove("is-open"); } }); } } }; document.addEventListener('DOMContentLoaded', app.init())
 :root { box-sizing: border-box; } *, *::before, *::after { box-sizing: inherit; } body { margin: 0; padding: 0; } .menu_active { background: rgba(0, 0, 0, 0.5); position: absolute; height: 100vh; width: calc(100vw - 200px); top: 0; right: 0; } .hidden { visibility: hidden; display: none; } .menu-toggle { width: 40px; height: 40px; border: 1px solid red; cursor: pointer; } .menu-container { position: absolute; background: lightskyblue; height: 100vh; width: 0; transition: width 0.4s ease-in-out; top: 0; left: 0; overflow: auto; z-index: 1; } .menu-close { position: absolute; right: 1em; } .nav-menu { list-style: none; padding-left: 0; margin: 50px 0 0 0; } .nav-menu>li+li { border-top: 1px solid #fff; } .nav-menu>li>a { display: block; color: #000; padding: 0.8em 1em; font-size: 1.1rem; text-decoration: none; text-transform: uppercase; } .nav.is-open .menu-container { width: 200px; } .menu-close::before { content: "\\00d7"; font-size: 2.6rem; } /*@media screen and (min-width: 37.5em) {*/ @media screen and (min-width: 40.5em) { body { background: #fff !important; } .menu-toggle { display: none; } .nav.is-open .menu-container { width: auto; height: auto; } .menu-container { position: initial; height: auto; width: auto; overflow: hidden; } .menu-close { display: none; } .nav-menu { display: flex; position: static; justify-content: center; margin: 0; } .nav-menu>li { margin-left: 1em; } .nav-menu>li+li { border-top: initial; } }
 <body> <nav class="nav"> <div class="menu-toggle"> <span class="menu-toggle__linecenter"></span> </div> <div class="menu-container"> <span class="menu-close"></span> <ul class="nav-menu"> <li><a href="#">Home</a></li> <li><a href="#">Menu Item 1</a></li> <li><a href="#">Menu Item 2</a></li> <li><a href="#">Menu Item 3</a></li> </ul> </div> <div class="menu_active hidden"></div> </nav> <main> <p> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusamus accusantium aliquid consequatur facere illum incidunt magnam magni maiores nam neque numquam omnis perferendis porro quae quibusdam, quos sed tenetur ullam. </p> </main> </body>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM