我构建了一个简单的侧面导航。如果您运行该代码段并将窗口调整为较小的尺寸,则会看到一个红色正方形。如果单击它,菜单将打开。
菜单打开正常,但是当我单击暗区而不是X时,我想关闭菜单。我尝试向主体本身添加“ click” eventListener并删除“ is-open”类,但是没用。我花了几个小时思考可能是什么问题,最后决定在这里发帖并征求您的建议。
"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>
答案 0 :(得分:2)
因此,如果我正确理解您要采取的措施,则您需要对点击事件使用open_basedir
而不是document
。您还需要使用body
而不是event.stopImmediatePropagation()
来允许第一次单击,但不允许第二次单击。同样,在这种情况下,只要单击菜单之外的任何地方,都只需要运行click事件即可。
注意:我不得不删除您的媒体查询,因为它阻止了切换菜单的显示。
event.preventDefault()
"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;
}
}
答案 1 :(得分:1)
这是您想要的,我在菜单旁边添加了一个带有类hidden
的新div,并且对于脚本,当event.target
等于该div或关闭按钮时,将触发功能。检查一下,让我知道是否有任何疑问。
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>