jQuery toggle based submenu toggles all submenus

别等时光非礼了梦想. 提交于 2021-02-08 10:48:32

问题


I'm new to jQuery/JS. The following is my attempt on a jQuery based menu with submenus. I'm not sure what to do here to fix this or where to go from here.

$(document).ready(function() {
  $(".toggle-btn").click(function() {
    $(this).toggleClass("active");
    $(".parent-nav").toggleClass("in");
  });
  $("#mainnav .child-nav > a").click(function() {
    $(this).toggleClass("active");
    $(".submenu").toggleClass("in");
    return false;
  });
});
body {
  padding: 20px 50px;
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  clip-path: inset(50%);
  border: 0; }


#mainnav {
  position: relative;
  z-index: 1;
  float: right;
  padding: 1.3rem 1rem;
  padding-right: 0; }
  #mainnav li:last-of-type .submenu {
    left: auto;
    right: 0; }
  #mainnav .toggle-btn {
    display: block;
    background: #fff;
    border: none;
    width: 42px;
    height: 42px;
    padding: 0;
    cursor: pointer; }
    #mainnav .toggle-btn:hover, #mainnav .toggle-btn:focus {
      background: #e9ecef; }
    #mainnav .toggle-btn:active, #mainnav .toggle-btn.active {
      background: #20ac62; }
      #mainnav .toggle-btn:active .bar, #mainnav .toggle-btn.active .bar {
        background: #fff; }
    #mainnav .toggle-btn .bar {
      display: block;
      background: #000;
      width: 24px;
      height: 3px;
      margin: 0 auto; }
      #mainnav .toggle-btn .bar + .bar {
        margin-top: 5px; }
  #mainnav .parent-nav,
  #mainnav .submenu {
    margin: 0;
    padding: 0;
    list-style: none; }
  #mainnav .parent-nav {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    visibility: hidden;
    opacity: 0;
    pointer-events: none;
    background: #f8f9fa;
    position: absolute;
    top: 100%;
    right: 0;
    width: calc(1110px - 120px);
    transition: all 0.3s; }
    @media (max-width: 1199px) {
      #mainnav .parent-nav {
        width: 220px;
        display: block; } }
    #mainnav .parent-nav.in {
      visibility: visible;
      opacity: 1;
      pointer-events: auto; }
    #mainnav .parent-nav a {
      position: relative;
      display: block;
      padding: 0.875rem 1.25rem;
      font-size: 0.875rem;
      font-weight: 700;
      color: #212529;
      line-height: 1.5rem;
      text-transform: uppercase;
      text-decoration: none; }
      #mainnav .parent-nav a:before {
        content: '';
        position: absolute;
        left: 0;
        bottom: 0;
        right: 0;
        height: 4px;
        background: #20ac62;
        opacity: 0;
        transition: all 0.15s; }
      #mainnav .parent-nav a:hover:before, #mainnav .parent-nav a:focus:before {
        opacity: 1; }
  #mainnav .child-nav {
    position: relative; }
    #mainnav .child-nav:hover .submenu, #mainnav .child-nav:focus .submenu {
      display: block; }
    #mainnav .child-nav a.active {
      background: #20ac62; }
    #mainnav .child-nav .caret {
      margin-left: 4px; }
    #mainnav .child-nav .submenu {
      position: absolute;
      top: 100%;
      left: 0;
      z-index: 1;
      display: none;
      background: #fff;
      min-width: 220px; }
      #mainnav .child-nav .submenu.in {
        min-width: 0;
        position: relative;
        display: block; }
      #mainnav .child-nav .submenu a {
        padding: 0.5rem 1rem;
        text-transform: none;
        font-weight: 400; }
        #mainnav .child-nav .submenu a:before {
          display: none; }
        #mainnav .child-nav .submenu a:hover, #mainnav .child-nav .submenu a:focus {
          background: #e9ecef; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<div id="mainnav">
  <button class="toggle-btn">
    <span class="sr-only">Menu</span>
    <span class="bar"></span>
    <span class="bar"></span>
    <span class="bar"></span>
  </button>
  <ul class="parent-nav">
    <li><a href="">Home</a></li>
    <li class="child-nav">
      <a href="">Properties <i class="fas fa-caret-down caret">˅</i></a>
      <ul class="submenu">
        <li><a href="">For Sale</a></li>
        <li><a href="">For Rent</a></li>
        <li><a href="">List Your Property</a></li>
      </ul>
    </li>
    <li><a href="">Services</a></li>
    <li><a href="">Contact Us</a></li>
    <li class="child-nav">
      <a href="">Company Group <i class="fas fa-caret-down caret">˅</i></a>
      <ul class="submenu">
        <li><a href="">Company Investments</a></li>
        <li><a href="">Company Hotels</a></li>
        <li><a href="">Company Developers</a></li>
        <li><a href="">Company Internship</a></li>
      </ul>
    </li>
  </ul>
</div>

As you can see in the above snippet, there are a pretty big problem. Tapping either of the sub-menus will trigger class .in on both of the .submenus, which obviously isn't the intended behavior. And I also don't know how to trigger this script after a certain viewport width.

How do I fix this?


回答1:


I've modified your javascript to include the jQuery function .next() to find the .submenu that comes after the link you clicked on rather than selecting all .submenus.

$(document).ready(function() {
  $(".toggle-btn").click(function() {
    $(this).toggleClass("active");
    $(".parent-nav").toggleClass("in");
  });
  $("#mainnav .child-nav > a").click(function() {
    $(this).toggleClass("active");
   $(this).next(".submenu").toggleClass("in");
    return false;
  });
});
body {
  padding: 20px 50px;
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  clip-path: inset(50%);
  border: 0; }


#mainnav {
  position: relative;
  z-index: 1;
  float: right;
  padding: 1.3rem 1rem;
  padding-right: 0; }
  #mainnav li:last-of-type .submenu {
    left: auto;
    right: 0; }
  #mainnav .toggle-btn {
    display: block;
    background: #fff;
    border: none;
    width: 42px;
    height: 42px;
    padding: 0;
    cursor: pointer; }
    #mainnav .toggle-btn:hover, #mainnav .toggle-btn:focus {
      background: #e9ecef; }
    #mainnav .toggle-btn:active, #mainnav .toggle-btn.active {
      background: #20ac62; }
      #mainnav .toggle-btn:active .bar, #mainnav .toggle-btn.active .bar {
        background: #fff; }
    #mainnav .toggle-btn .bar {
      display: block;
      background: #000;
      width: 24px;
      height: 3px;
      margin: 0 auto; }
      #mainnav .toggle-btn .bar + .bar {
        margin-top: 5px; }
  #mainnav .parent-nav,
  #mainnav .submenu {
    margin: 0;
    padding: 0;
    list-style: none; }
  #mainnav .parent-nav {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    visibility: hidden;
    opacity: 0;
    pointer-events: none;
    background: #f8f9fa;
    position: absolute;
    top: 100%;
    right: 0;
    width: calc(1110px - 120px);
    transition: all 0.3s; }
    @media (max-width: 1199px) {
      #mainnav .parent-nav {
        width: 220px;
        display: block; } }
    #mainnav .parent-nav.in {
      visibility: visible;
      opacity: 1;
      pointer-events: auto; }
    #mainnav .parent-nav a {
      position: relative;
      display: block;
      padding: 0.875rem 1.25rem;
      font-size: 0.875rem;
      font-weight: 700;
      color: #212529;
      line-height: 1.5rem;
      text-transform: uppercase;
      text-decoration: none; }
      #mainnav .parent-nav a:before {
        content: '';
        position: absolute;
        left: 0;
        bottom: 0;
        right: 0;
        height: 4px;
        background: #20ac62;
        opacity: 0;
        transition: all 0.15s; }
      #mainnav .parent-nav a:hover:before, #mainnav .parent-nav a:focus:before {
        opacity: 1; }
  #mainnav .child-nav {
    position: relative; }
    #mainnav .child-nav:hover .submenu, #mainnav .child-nav:focus .submenu {
      display: block; }
    #mainnav .child-nav a.active {
      background: #20ac62; }
    #mainnav .child-nav .caret {
      margin-left: 4px; }
    #mainnav .child-nav .submenu {
      position: absolute;
      top: 100%;
      left: 0;
      z-index: 1;
      display: none;
      background: #fff;
      min-width: 220px; }
      #mainnav .child-nav .submenu.in {
        min-width: 0;
        position: relative;
        display: block; }
      #mainnav .child-nav .submenu a {
        padding: 0.5rem 1rem;
        text-transform: none;
        font-weight: 400; }
        #mainnav .child-nav .submenu a:before {
          display: none; }
        #mainnav .child-nav .submenu a:hover, #mainnav .child-nav .submenu a:focus {
          background: #e9ecef; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<div id="mainnav">
  <button class="toggle-btn">
    <span class="sr-only">Menu</span>
    <span class="bar"></span>
    <span class="bar"></span>
    <span class="bar"></span>
  </button>
  <ul class="parent-nav">
    <li><a href="">Home</a></li>
    <li class="child-nav">
      <a href="">Properties <i class="fas fa-caret-down caret">˅</i></a>
      <ul class="submenu">
        <li><a href="">For Sale</a></li>
        <li><a href="">For Rent</a></li>
        <li><a href="">List Your Property</a></li>
      </ul>
    </li>
    <li><a href="">Services</a></li>
    <li><a href="">Contact Us</a></li>
    <li class="child-nav">
      <a href="">Company Group <i class="fas fa-caret-down caret">˅</i></a>
      <ul class="submenu">
        <li><a href="">Company Investments</a></li>
        <li><a href="">Company Hotels</a></li>
        <li><a href="">Company Developers</a></li>
        <li><a href="">Company Internship</a></li>
      </ul>
    </li>
  </ul>
</div>


来源:https://stackoverflow.com/questions/49442684/jquery-toggle-based-submenu-toggles-all-submenus

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!