JavaScript:调整笔记本电脑浏览器窗口的大小(“移动”-“桌面”-“移动”)不会重新启动菜单状态

时间:2018-08-23 16:43:07

标签: javascript html css browser resize

我使用最新的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;
        menu.style.display = 'none';
      } 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>

4 个答案:

答案 0 :(得分:2)

问题是,当浏览器宽度最初调整为<= 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';
      }
    }
  });
});

答案 1 :(得分:2)

您使用了太多的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>

答案 2 :(得分:1)

如果您想针对某个断点并在命中大小时运行某些代码,则可以使用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操作,则可能需要throttle resize event

答案 3 :(得分:0)

如果我理解这个问题,那么您正在尝试完成以下任务:

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

其他答案已经解决了上述一项或多项,但并非全部。以下是将它们组合在一起的方法;但是,我建议您不要实施上面的“ 3b”,除非您的应用程序或网站有不同寻常的用例(我认为大多数临时用户不会将屏幕的大小从移动设备调整为台式机,然后再经常调整为移动设备尺寸,但是也许我错了,而且我不知道如果有人进行了这种调整大小的实验,那么如果下拉菜单仍然可见的话,那将不会很重要。

我添加了一些其他htmlcss用于样式设置,因为很难从视觉上看到切换菜单显示和使用spartan设置调整屏幕大小的效果(还处理了具有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>