【问题标题】:Slide over navigation bar滑过导航栏
【发布时间】:2020-02-09 16:44:44
【问题描述】:

我一直在尝试创建一个“在导航栏上滑动”的想法是我希望它可以滑动超过 100% 的页面宽度,不透明度设置为 0.7 左右,并将 2 行汉堡栏转换为一个十字架。

我已经成功创建了汉堡吧并对其进行了改造。当我单击它时,我无法关闭导航幻灯片!它也来自左侧,并希望它来自右侧!

我还不够熟练,无法完全理解 JavaScript 是如何工作的,以及这是否会干扰打开-关闭功能。另外,我不确定我最近做了什么,但它现在似乎完全消失了!

const menuBtn = document.querySelector('.menu-btn');
let menuOpen = false;
menuBtn.addEventListener('click', () => {
  if (!menuOpen) {
    menuBtn.classList.add('open');
    menuOpen = true;
  } else {
    menuBtn.classList.remove('open');
    menuOpen = false;
  }
});
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  background: white;
  min-height: 100vh;
}

.menu-btn {
  position: absolute;
  top: 25px;
  left: 95%;
  width: 40px;
  height: 40px;
  cursor: pointer;
  transition: all.5s ease-in-out;
  z-index: 2;
}

.menu-btn-burger::before,
.menu-btn-burger::after {
  content: '';
  position: absolute;
  width: 30px;
  height: 3px;
  background: black;
  border-radius: 2px;
  transition: all .5s ease-in-out;
}

.menu-btn-burger::after {
  transform: translateY(16px);
}

.menu-btn.open .menu-btn-burger::before {
  transform: rotate(45deg);
}

.menu-btn.open .menu-btn-burger::after {
  transform: rotate(-45deg);
}

.logobrand {
  height: 200px;
  position: absolute;
  top: 9%;
  left: 4%;
  z-index: 3;
}

.btn a {
  padding: 5px;
}

.btn {
  font-family: Montserrat;
  font-weight: lighter;
  font-size: 12px;
  text-transform: uppercase;
  text-decoration: none;
  color: black;
  position: absolute;
  top: 2%;
  right: 10%;
  border: solid 1px black;
  padding: 5px;
  border-radius: 4px;
}

.btn:hover {
  background-color: black;
  transition: 1s;
  opacity: 0.7;
  color: white;
}

.work {
  width: 100%;
  height: 100%;
  background-position: center;
  background-size: cover;
  background-repeat: no-repeat;
  opacity: 0.7;
  overflow-y: hidden;
}

.listitems {
  position: absolute;
  left: 70%;
  top: 30%;
}

.side-nav {
  height: 100%;
  width: 0;
  position: fixed;
  z-index: 1;
  top: 0;
  left: 0;
  background-color: black;
  opacity: 0.7;
  overflow-x: hidden;
  padding-top: 60px;
  transition: 1s;
  transform: translateX(99%);
}

.side-nav a {
  padding: 10px 10px 10px 30px;
  text-decoration: none;
  font-size: 30px;
  color: white;
  display: block;
  transition: 0.5s;
  font-family: Montserrat;
  list-style: none;
}

.side-nav a:hover {
  color: silver;
}

.side-nav .btn-close {
  position: absolute;
  top: 0;
  left: 0px;
}

a li {
  width: 220px;
}

.instagram {
  height: 35px;
  padding: 5px;
}

.facebook {
  height: 35px;
  padding: 5px;
}

.twitter {
  height: 35px;
  padding: 5px;
}

.linkedin {
  height: 35px;
  padding: 5px;
}

.social {
  position: absolute;
  top: 95%;
  left: 88%;
  display: block;
}

.copy {
  text-align: center;
  font-family: Montserrat;
}
<link rel="stylesheet" href="https://unpkg.com/aos@next/dist/aos.css" />

<video class="work" autoplay loop muted src="img/Video.mov"></video>
<nav class="navbar">
  <span class="open-slide">
      <a href="#" onclick="openSlideMenu()">
          <div class="menu-btn" onclick="show()">
              <div class="menu-btn-burger"></div>
          </div>
      </a>
  </span>
</nav>
<a class="btn" href="#">
  <h3>Request a Quote</h3>
</a>
<div id="side-menu" class="side-nav">
  <a href="#" class="btn-close" onclick="closeSlideMenu()">
    <div class="menu-btn" onclick="show()">
      <div class="menu-btn-burger"></div>
    </div>
    <div class="listitems">
      <a href="#">
        <li>Who we are</li>
      </a>
      <a href="#">
        <li>What we offer</li>
      </a>
      <a href="#">
        <li>How can we help?</li>
      </a>
      <a href="#">
        <li>Chat to us</li>
      </a>
    </div>
  </a>
</div>
<div class="logo"><img class="logobrand" src="img/Chatting Creative logo.png" alt=""></div>

<div class="social">
  <img class="instagram" src="img/1t.png" alt="">
  <img class="facebook" src="img/2t.png" alt="">
  <img class="twitter" src="img/3t.png" alt="">
  <img class="linkedin" src="img/4t.png" alt="">
</div>

<footer>
  <p class="copy">
    &copy; Chatting Creative 2020
  </p>
</footer>

<script>
  function openSlideMenu() {
    document.getElementById('side-menu').style.width = '100%';
    document.getElementById('main').style.marginLeft = '250px';
  }

  function closeSlideMenu() {
    document.getElementById('side-menu').style.width = '0px';
    document.getElementById('main').style.marginLeft = '0px';
  }
</script>
<script src="https://unpkg.com/aos@next/dist/aos.js"></script>
<script>
  AOS.init();
</script>

【问题讨论】:

  • 您能否将示例简化为工作 minimal reproducible example(删除与问题不直接相关的任何内容)。
  • &lt;a&gt;锚点内不能有其他动作元素。
  • &lt;span&gt; 中放置 &lt;div&gt; 是无效的标记,在 &lt;a&gt; 中放置 &lt;li&gt; 元素也是无效的。 LI 的父级应该是 UL 或 OL

标签: javascript html css navbar


【解决方案1】:

两个例子,一个使用 HTML+CSS,一个使用 JavaScript

使用复选框

您可以使用隐藏的复选框来代替 JS。
查看此示例并在代码中查找 cmets。

* {margin: 0; padding: 0; box-sizing: border-box;}

body {
  min-height: 100vh;
  height: 200vh;   /* JUST FOR DEMO - remove this afterwards. */
  border: 4px dashed #000;
}

#btn-burger { /* Use ID. You need only one of these */
  position: fixed; /* make it fixed */
  z-index: 2;
  top: 25px;
  right: 25px; /* use right */
  width: 30px; /* should be 30, not 40 */
  height: 30px;
  cursor: pointer;
}
#btn-burger::before,
#btn-burger::after {
  content: '';
  position: absolute;
  width: 30px;
  height: 3px;
  background: #000;
  transition: all .5s ease-in-out;
}
#btn-burger::after { transform: translateY(16px); }

#side-menu {
  position: fixed;
  z-index: 1;
  height: 100%;
  /* Do not use width 0 */
  top: 0;
  right: 0;    /* Use right 0 */
  background-color: #ddd;
  overflow-x: hidden;
  padding-top: 60px;
  transition: 1s;
  transform: translateX(100%); /* Use 100% */
}

#side-menu a {
  padding: 5px 20px;
  display: block;
}

#menuHandler:checked ~ #btn-burger::before { transform: rotate(45deg); }
#menuHandler:checked ~ #btn-burger::after  { transform: rotate(-45deg); }
#menuHandler:checked ~ #side-menu { transform: translateX(0%); } /* do not use width here */
<input id="menuHandler" type="checkbox" hidden />

<label id="btn-burger" for="menuHandler"></label>

<div id="side-menu">
  <ul class="listItems">
    <li><a href="#">Who we are</a></li>
    <li><a href="#">What we offer</a></li>
    <li><a href="#">How can we help?</a></li>
    <li><a href="#">Chat to us</a></li>
  </ul>
</div>

另外记住:

  • &lt;a&gt; 锚点中包含其他操作元素是无效的。
  • &lt;span&gt; 中放置&lt;div&gt; 是无效标记
  • &lt;a&gt; 中包含 &lt;li&gt; 元素也是无效的。 LIs 父级应该是 &lt;ul&gt;&lt;ol&gt;

使用 JavaScript 的示例

点击后,您只需执行Element.classList.toggle()

const EL_burger = document.querySelector("#btn-burger");
const EL_menu = document.querySelector("#side-menu");
const EL_listItems = EL_menu.querySelectorAll("a");

const toggleSideMenu = (ev) => {
  ev.preventDefault();
  EL_menu.classList.toggle('is-open');
  EL_burger.classList.toggle('is-open');
}

EL_burger.addEventListener('click', toggleSideMenu);

// If your're building a singlePage app than you'll also need this:
EL_listItems.forEach(el => el.addEventListener('click', toggleSideMenu));
* {margin: 0; padding: 0; box-sizing: border-box;}

body {
  min-height: 100vh;
  height: 200vh;   /* JUST FOR DEMO - remove this afterwards. */
  border: 4px dashed #000;
}

#btn-burger { /* Use ID. You need only one of these */
  position: fixed; /* make it fixed */
  z-index: 2;
  top: 25px;
  right: 25px; /* use right */
  width: 30px; /* should be 30, not 40 */
  height: 30px;
  cursor: pointer;
}
#btn-burger::before,
#btn-burger::after {
  content: '';
  position: absolute;
  width: 30px;
  height: 3px;
  background: #000;
  transition: all .5s ease-in-out;
}
#btn-burger::after { transform: translateY(16px); }

#side-menu {
  position: fixed;
  z-index: 1;
  height: 100%;
  /* Do not use width 0 */
  top: 0;
  right: 0;    /* Use right 0 */
  background-color: #ddd;
  overflow-x: hidden;
  padding-top: 60px;
  transition: 1s;
  transform: translateX(100%); /* Use 100% */
}

#side-menu a {
  padding: 5px 20px;
  display: block;
}

#btn-burger.is-open::before { transform: rotate(45deg); }
#btn-burger.is-open::after  { transform: rotate(-45deg); }
#side-menu.is-open { transform: translateX(0%); } /* do not use width here */
<a id="btn-burger"></a>

<div id="side-menu">
  <ul class="listItems">
    <li><a href="#">Who we are</a></li>
    <li><a href="#">What we offer</a></li>
    <li><a href="#">How can we help?</a></li>
    <li><a href="#">Chat to us</a></li>
  </ul>
</div>

【讨论】:

  • 这可能是更好的规范答案+1
【解决方案2】:

目前,您似乎尝试实施至少三种不同的方法来解决此问题。我建议您从核心功能重新开始。您可以在下面找到一种可能的方法。我试图靠近你的代码。

有很多方法可以达到你想要的效果。我使用了通过Element.classList.toggle('class') 切换onoff 的HTML 类,每次点击menuBtn。然后所有样式更改都由 CSS 应用,因为它在那里定义 #side-menu.open#side-menu 的样式略有不同(没有 open-class 时相同)。

const menuBtn = document.getElementById('menu-btn');
const menuItems = document.getElementById('side-menu');

menuBtn.addEventListener('click', () => {
  menuBtn.classList.toggle("open");
  menuItems.classList.toggle("open");
});
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  background: white;
  min-height: 100vh;
}

#menu-btn {
  position: absolute;
  top: 25px;
  right: 15px;
  width: 40px;
  height: 40px;
  cursor: pointer;
  z-index: 2;
}

#menu-btn:before,
#menu-btn:after {
  content: '';
  position: absolute;
  width: 30px;
  height: 3px;
  background: #000;
  border-radius: 5px;
  transition: all .2s ease-in-out;
}

#menu-btn:after {
  transform: translateY(16px);
}

#menu-btn.open:before {
  transform: rotate(45deg);
  background: #fff;
}

#menu-btn.open:after {
  transform: rotate(-45deg);
  background: #fff;
}

#side-menu {
  position: fixed;
  height: 100%;
  width: 0;
  top: 0;
  left: 0;
  background-color: rgba(0, 0, 0, .7);
  padding-top: 60px;
  transition: .4s;
  overflow-x: hidden;
}

#side-menu.open {
  width: 100%;
  right: 0;
}

#side-menu a {
  padding: 10px 10px 10px 30px;
  text-decoration: none;
  font-size: 30px;
  display: block;
  font-family: Montserrat;
  list-style: none;
  color: #fff;
  opacity: 0;
  transition: .3s;
  white-space: nowrap;
}

#side-menu.open a {
  opacity: 1;
  transition: .1s;
}

#side-menu a:hover {
  color: silver;
}
<div id="menu-btn"></div>
<div id="side-menu">
  <a href="#">
    <li>Who we are</li>
  </a>
  <a href="#">
    <li>What we offer</li>
  </a>
  <a href="#">
    <li>How can we help?</li>
  </a>
  <a href="#">
    <li>Chat to us</li>
  </a>
</div>

【讨论】:

  • 真的很感激谢谢,这很好用。我同意我的代码到处都是我从头开始学习大约 2 个月的地方,因此为混乱和所有不需要的额外信息道歉!最佳康纳
  • @ConnorChatt 很高兴,它有帮助!有时最好从头开始,而不是与自己的旧代码作斗争^^
【解决方案3】:

对于初学者:您可以在不保持状态的情况下切换类(添加/删除),请查看此处的示例: https://developer.mozilla.org/en-US/docs/Web/API/Element/classList

menuBtn.classList.toggle('open')

看看这是否能解决您的问题并重新了解变量范围的工作原理: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let

一般来说,社区更喜欢可以在未来帮助其他人的问题,这与您遇到的问题非常具体。不管怎样,祝你好运,欢迎来到 StackOverflow :)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-05-07
    • 2021-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-01
    • 1970-01-01
    相关资源
    最近更新 更多