JavaScript:调整笔记本电脑浏览器窗口的大小("mobile" - "desktop" - "mobile")不会重新启动菜单状态



我使用最新的Google Chrome,我有以下前端代码用于我在WordPress网站中使用的响应式导航菜单。

单击.burger元素会使相邻的.menu元素分别在下拉列表或下拉列表中显示或消失。

我的问题

  1. 我们打开一个浏览器窗口<=959px然后打开移动菜单。
  2. 我们将窗口大小调整为>=960px,然后调整回<=959px
  3. 我们必须单击burger两次才能关闭菜单,然后重新打开它。

我的问题

为什么在给定的情况下我们需要点击汉堡两次?

法典

document.addEventListener('DOMContentLoaded', ()=>{
let clicks = 0;
let menu = document.querySelector('#menu-primary');
let burger = document.querySelector('.burger');
let isMenuVisible = false;
burger.addEventListener('click', ()=>{
isMenuVisible = !isMenuVisible;
menu.style.display = isMenuVisible ? 'block' : 'none';
});
let mobileBehavior = ()=>{
menu.style.display = 'none';
};
if (window.innerWidth <= 959) {
mobileBehavior();
}
window.addEventListener('resize', ()=>{
if (window.innerWidth <= 959) {
clicks = 1;
} else if (window.innerWidth >= 960) {
menu.style.display = 'block';
}
});
});
.burger {
display: block;
text-align: center; color: var(--w);
margin-bottom: 0 !important;
font-weight: bold
}
#menu-primary { display: none }
@media screen and (min-width: 960px) {
.burger { display: none }
#menu-primary { display: block }
}
<div class="burger">BARS</div>
<ul id="menu-primary">
<li>Homepage</li>
<li>Contact_us</li>
</ul>

你使用了太多的javascript,你可以通过在单击栏并将"逻辑"放在css中时在元素上切换一个类来简化它。

document.addEventListener('DOMContentLoaded', ()=>{
let menu = document.querySelector('#menu-primary');
let burger = document.querySelector('.burger');
burger.addEventListener('click', ()=>{
menu.classList.toggle('collapse');
});
});
.burger {
display: block;
text-align: center; color: var(--w);
margin-bottom: 0 !important;
font-weight: bold;
cursor: pointer;
}
#menu-primary.collapse{
display: none;
}
@media screen and (min-width: 960px) {
.burger { display: none }
#menu-primary.collapse{
display: block;
}
}
<div class="burger">BARS</div>
<ul id="menu-primary">
<li>Homepage</li>
<li>Contact_us</li>
</ul>

问题是当浏览器宽度最初调整为<= 959时,您没有关闭菜单。为了有效地做到这一点,你只需要一个布尔变量来控制菜单关闭,这样它只在断点发生一次,然后在浏览器宽度调整为>= 960时重置。

document.addEventListener('DOMContentLoaded', () => {
const menu = document.querySelector('#menu-primary');
const burger = document.querySelector('.burger');
const breakpoint = 959;
let switched = false;
burger.addEventListener('click', () => {
menu.style.display = menu.style.display !== 'block' ? 'block' : 'none';
});
if (window.innerWidth <= breakpoint) {
menu.style.display = 'none';
switched = true;
}
window.addEventListener('resize', () => {
if (window.innerWidth <= breakpoint) {
if (!switched) {
switched = true;
menu.style.display = 'none';
}
} else {
if (switched) {
switched = false;
menu.style.display = 'block';
}
}
});
});

如果要以某个断点为目标并在调整大小时运行一些代码,则可以使用window.matchMedia,它也适用于断点范围。

window.addEventListener("resize", function () {
// single breakpoint
if (window.matchMedia("(max-width:768px)").matches) {
// your logic here        
}
// you can target breakpoint range as well
// window.matchMedia("(min-width:375px) and (max-width:768px)").matches
});

附带说明一下,如果您正在执行昂贵的 dom 操作,则可能需要限制调整大小事件。

如果我理解这个问题,您正在尝试完成以下操作:

  1. 创建在click事件中打开和关闭的汉堡包样式下拉菜单或导航抽屉。
  2. 仅在移动屏幕上显示汉堡包和相关菜单。
  3. 如果在汉堡菜单打开时将移动大小的屏幕调整为桌面大小:a( 汉堡包和相关菜单都是隐藏的,并且 b( 菜单显示是"重置"的,以便如果屏幕调整回移动大小,则会显示汉堡包,但相关菜单不会。

其他答案涉及上述一项或多项,但不是全部。以下是将它们放在一起的方法;但是,我建议不要实现上面的"3b",除非您的应用程序或网站有一个不寻常的用例(我不认为大多数临时用户经常将屏幕大小从移动设备调整为桌面设备,然后再调整回移动设备尺寸,但也许我错了,我不知道如果有人确实进行了这种调整大小,下拉菜单是否仍然可见会有多重要实验(。

我添加了一些额外的htmlcss用于样式目的,因为很难直观地看到切换菜单显示和使用斯巴达设置调整屏幕大小的效果(还处理了具有visibility属性和position: absolute的菜单显示,以便在切换显示时不会影响其他元素的位置。

用于特定目的的功能代码是.burger.burger-menu.hidden.desktop类(包括相关的媒体查询(的 javascript 和 css 样式。

const burger = document.querySelector('.burger');
const burgerMenu = document.querySelector('.burger-menu');
burger.addEventListener('click', () => {
burgerMenu.classList.toggle('hidden');
});
// not recommended (but this "resets" the menu display on resize)
window.addEventListener("resize", () => {
if (window.matchMedia('(min-width:960px)').matches) {
burgerMenu.classList.add('hidden');
}
});
nav {
background-color: #000;
color: #fff;
margin-bottom: 16px;
}
nav ul:first-child {
display: inline;
padding: 0;
}
nav ul li {
padding: 8px 16px;
}
.burger {
display: inline-block;
}
.burger div {
background-color: #fff;
margin: 4px 0;
width: 24px;
height: 3px;
}
.burger-menu {
background-color: #000;
padding: 4px;
position: absolute;
list-style: none;
}
.hidden {
visibility: hidden;
}
.desktop {
display: none;
}
@media screen and (min-width: 960px) {
.burger {
display: none;
}
.burger-menu {
visibility: hidden;
}
.desktop {
display: inline-block;
}
}
<nav>
<ul>
<li class="burger">
<div></div>
<div></div>
<div></div>
</li>
<ul class="burger-menu hidden">
<li>Home (mobile)</li>
<li>Contact (mobile)</li>
</ul>
<li class="desktop">Home (desktop)</li>
<li class="desktop">Contact (desktop)</li>
</ul>
</nav>
<div>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus vel augue ipsum. Donec suscipit nisi magna, ac condimentum est blandit a.
</div>

相关内容

最新更新