slideUp / slideDown сдвигает оба (все) подменю - PullRequest
1 голос
/ 25 февраля 2020

Я создаю боковую панель, используя HTML, CSS и jQuery. У меня проблема с slideUp / slideDown не работает правильно. Например, когда я пытаюсь щелкнуть по подменю, чтобы закрыть его, оба открытых подменю исчезают. Нажатие на подменю, чтобы открыть их, также работает неправильно. Мне интересно, почему это происходит. Я не уверен, что я сделал не так.

Я пытался console.log($(this).find('> .submenu'));, и действительно, объект имеет длину 1. Я не уверен, почему он сдвигает оба (все) меню.

$(document).ready(function() {
  $('.has-submenu').click(function() {
    $(this).toggleClass('active');
    $(this).find('> .menu-item > .arrow').toggleClass('rotated');
    if ($(this).hasClass('active')) {
      $(this).find('> .submenu').slideDown("slow");
    } else {
      console.log($(this).find('> .submenu'));
      $(this).find('> .submenu').slideUp("slow");
    }
  });
});
@import url(https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,300,600);
@font-face {
  font-family: "ionicons";
  src: url("https://code.ionicframework.com/ionicons/2.0.1/fonts/ionicons.eot?v=2.0.1");
  src: url("https://code.ionicframework.com/ionicons/2.0.1/fonts/ionicons.eot?v=2.0.1#iefix") format("embedded-opentype"), url("https://code.ionicframework.com/ionicons/2.0.1/fonts/ionicons.ttf?v=2.0.1") format("truetype"), url("https://code.ionicframework.com/ionicons/2.0.1/fonts/ionicons.woff?v=2.0.1") format("woff"), url("https://code.ionicframework.com/ionicons/2.0.1/fonts/ionicons.svg?v=2.0.1#Ionicons") format("svg");
  font-weight: normal;
  font-style: normal;
}

.sidebar {
  width: 200px;
  height: 100vh;
  padding: 1rem 1.5rem;
  background-color: #348ceb;
  font-family: 'Source Sans Pro';
  font-size: 14px;
  position: fixed;
  box-sizing: border-box;
}

ul {
  list-style: none;
}

ul,
li {
  padding: 0;
  margin: 0;
}

li {
  padding: 0.5rem 0;
  cursor: pointer;
}

.submenu {
  width: 200px;
  overflow-x: hidden;
  display: none;
  overflow-y: hidden;
  margin: 0 -1.5rem;
  background-color: #3287e3;
}

.submenu li:first-child {
  padding: 0.1rem 0 0 1.5rem;
}

.submenu li:last-child {
  padding: 0 0 0.1rem 1.5rem;
}

.submenu li {
  padding: 0.5rem 1.5rem;
}

.submenu li:hover {
  background-color: #3082db;
}

.menu>li:hover {
  background-color: #3287e3;
}

.menu>li {
  position: relative;
  color: #F9FAFC;
  font-weight: bold;
  margin: 0 -1.5rem;
  padding: 0.5rem 1.5rem;
}

.menu>li>a {
  display: block;
  color: #F9FAFC;
  text-decoration: none;
  font-weight: bold;
}

.menu>li>a:hover {
  color: white;
}

.submenu>li>a {
  display: block;
  color: #F9FAFC;
  text-decoration: none;
  margin: 0 -1.5rem;
  padding: 0 1.5rem;
}

.submenu>li>a:hover {
  color: white;
}

.submenu>li {
  font-weight: normal !important;
}

.arrow {
  display: inline-block;
  width: 10px;
  transition: all 0.5s ease-in-out;
  transform-origin: left center;
  font-size: 0.5em;
  position: absolute;
  right: 0.75em;
}

.arrow:after {
  content: '\f125';
  font-family: 'ionicons';
  color: white;
}

.rotated {
  transform: rotate(90deg);
  transition: transform 0.5s ease;
}

.menu-item {
  display: flex;
  align-items: center;
}

.menu-item>span:first-child {
  flex: 1;
}

.sidebar-icon {
  background-repeat: no-repeat;
  padding-left: 25px;
}

.no-submenu a {
  margin: 0 -1.5rem;
  padding: 0 1.5rem;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<div class="sidebar">
  <nav>
    <ul class="menu">
      <li class="has-submenu">
        <div class="menu-item">
          <span>Analytic plane geometry</span>
          <span class="arrow"></span>
        </div>
        <ul class="submenu">
          <li class="has-submenu">
            <div class="menu-item">
              <span>Line</span>
              <span class="arrow"></span>
            </div>
            <ul class="submenu">
              <li>1</li>
              <li>2</li>
            </ul>
          </li>
          <li class="has-submenu">
            <div class="menu-item">
              <span>Circle</span>
              <span class="arrow"></span>
            </div>
            <ul class="submenu">
              <li>1</li>
              <li>2</li>
            </ul>
          </li>
        </ul>
      </li>
    </ul>
  </nav>
</div>

Вот демоверсия .

1 Ответ

1 голос
/ 25 февраля 2020

Проблема в том, что элементы .has-submenu являются вложенными. Таким образом, когда вы щелкаете дочерний элемент, событие распространяется вверх по DOM и запускается там, поэтому все элементы переключаются. Чтобы исправить этот вызов stopPropagation() для события, которое передается обработчику:

$('.has-submenu').click(function(e) {
  e.stopPropagation();
  // the rest of your code...
});

Кроме того, вам следует кэшировать селекторы, чтобы сохранить воссоздание объекта jQuery из this, и вы также можно устранить необходимость в условии if, используя вместо этого slideToggle(). Попробуйте это:

jQuery(function($) {
  $('.has-submenu').click(function(e) {
    e.stopPropagation();

    var $el = $(this).toggleClass('active');
    $el.find('> .menu-item > .arrow').toggleClass('rotated');
    $el.find('> .submenu').slideToggle("slow");
  });
});
@import url(https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,300,600);
@font-face {
  font-family: "ionicons";
  src: url("https://code.ionicframework.com/ionicons/2.0.1/fonts/ionicons.eot?v=2.0.1");
  src: url("https://code.ionicframework.com/ionicons/2.0.1/fonts/ionicons.eot?v=2.0.1#iefix") format("embedded-opentype"), url("https://code.ionicframework.com/ionicons/2.0.1/fonts/ionicons.ttf?v=2.0.1") format("truetype"), url("https://code.ionicframework.com/ionicons/2.0.1/fonts/ionicons.woff?v=2.0.1") format("woff"), url("https://code.ionicframework.com/ionicons/2.0.1/fonts/ionicons.svg?v=2.0.1#Ionicons") format("svg");
  font-weight: normal;
  font-style: normal;
}

.sidebar {
  width: 200px;
  height: 100vh;
  padding: 1rem 1.5rem;
  background-color: #348ceb;
  font-family: 'Source Sans Pro';
  font-size: 14px;
  position: fixed;
  box-sizing: border-box;
}

ul {
  list-style: none;
}

ul,
li {
  padding: 0;
  margin: 0;
}

li {
  padding: 0.5rem 0;
  cursor: pointer;
}

.submenu {
  width: 200px;
  overflow-x: hidden;
  display: none;
  overflow-y: hidden;
  margin: 0 -1.5rem;
  background-color: #3287e3;
}

.submenu li:first-child {
  padding: 0.1rem 0 0 1.5rem;
}

.submenu li:last-child {
  padding: 0 0 0.1rem 1.5rem;
}

.submenu li {
  padding: 0.5rem 1.5rem;
}

.submenu li:hover {
  background-color: #3082db;
}

.menu>li:hover {
  background-color: #3287e3;
}

.menu>li {
  position: relative;
  color: #F9FAFC;
  font-weight: bold;
  margin: 0 -1.5rem;
  padding: 0.5rem 1.5rem;
}

.menu>li>a {
  display: block;
  color: #F9FAFC;
  text-decoration: none;
  font-weight: bold;
}

.menu>li>a:hover {
  color: white;
}

.submenu>li>a {
  display: block;
  color: #F9FAFC;
  text-decoration: none;
  margin: 0 -1.5rem;
  padding: 0 1.5rem;
}

.submenu>li>a:hover {
  color: white;
}

.submenu>li {
  font-weight: normal !important;
}

.arrow {
  display: inline-block;
  width: 10px;
  transition: all 0.5s ease-in-out;
  transform-origin: left center;
  font-size: 0.5em;
  position: absolute;
  right: 0.75em;
}

.arrow:after {
  content: '\f125';
  font-family: 'ionicons';
  color: white;
}

.rotated {
  transform: rotate(90deg);
  transition: transform 0.5s ease;
}

.menu-item {
  display: flex;
  align-items: center;
}

.menu-item>span:first-child {
  flex: 1;
}

.sidebar-icon {
  background-repeat: no-repeat;
  padding-left: 25px;
}

.no-submenu a {
  margin: 0 -1.5rem;
  padding: 0 1.5rem;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<div class="sidebar">
  <nav>
    <ul class="menu">
      <li class="has-submenu">
        <div class="menu-item">
          <span>Analytic plane geometry</span>
          <span class="arrow"></span>
        </div>
        <ul class="submenu">
          <li class="has-submenu">
            <div class="menu-item">
              <span>Line</span>
              <span class="arrow"></span>
            </div>
            <ul class="submenu">
              <li>1</li>
              <li>2</li>
            </ul>
          </li>
          <li class="has-submenu">
            <div class="menu-item">
              <span>Circle</span>
              <span class="arrow"></span>
            </div>
            <ul class="submenu">
              <li>1</li>
              <li>2</li>
            </ul>
          </li>
        </ul>
      </li>
    </ul>
  </nav>
</div>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...