Двухуровневое меню-гармошка HTML скрывает и не добавляет содержимое

Я пытаюсь сделать двухуровневое аккордеонное меню. Первый уровень работает нормально, но когда я добавляю второй уровень, содержимое второго уровня скрывается в заголовке Раздела 2 первого уровня. Кто-то знает, как я могу это решить?

Мой html-код таков:

<div class = "container-wrapper"></div>
    <button class = "accordion"><p class = "title-sections">Provisioning</p></button>
    <div class = "panel">
        <button class = "sub-accordion">Set Variables</button>
        <div class = "sub-panel">
            <p>Lorem ipsum...</p>
        </div>
        <button class = "sub-accordion">Get Variables</button>
        <div class = "sub-panel">
            <p>Lorem ipsum...</p>
         </div>
         <button class = "sub-accordion">Reset</button>
         <div class = "sub-panel">
             <p>Lorem ipsum...</p>
         </div>
         <button class = "sub-accordion">Get Base Report</button>
         <div class = "sub-panel">
             <p>Lorem ipsum...</p>
         </div>
         </div>
    
     <button class = "accordion"><p class = "title-sections">Availability</p></button>
     <div class = "panel">
         <p>Lorem ipsum...</p>
     </div>

Мой CSS:

.accordion {
        background-color: #eee;
        color: #444;
        cursor: pointer;
        padding: 18px;
        width: 100%;
        text-align: left;
        border: none;
        outline: none;
        transition: 0.4s;
    }

    .sub-accordion {
        background-color: rgb(181, 255, 191);
        color: #444;
        cursor: pointer;
        padding: 18px;
        width: 100%;
        text-align: center;
        border: none;
        outline: none;
        transition: 0.4s;
    }

    .active, .accordion:hover {
       background-color: #ccc;
    }

    .sub-active, .sub-accordion:hover {
        background-color: rgb(104, 255, 124);;
    }

    .panel {
      padding: 0 18px;
      background-color: white;
      max-height: 0;
      overflow: hidden;
      transition: max-height 0.2s ease-out;
    }

    .sub-panel {
        padding: 0 18px;
        background-color: lightblue;
        max-height: 0;
        overflow: hidden;
        transform: max-height 0.2s ease-out;
    }

    .container-wrapper {
        padding: 20pt;
    }

    .title-sections {
        font-size: 20px;
    }

И, наконец, мой JS, вот в чем проблема. Я скопировал тот же код аккордеона первого уровня, чтобы сделать аккордеон второго уровня, и есть проблема с высотой, но я не совсем знаю, какую часть нужно изменить:

var acc = document.getElementsByClassName("accordion");
var i;
var sub_acc = document.getElementsByClassName("sub-accordion");
var j;


for (i = 0; i < acc.length; i++) {
  acc[i].addEventListener("click", function() {
    this.classList.toggle("active");
    var panel = this.nextElementSibling;
    if (panel.style.maxHeight) {
      panel.style.maxHeight = null;
    } else {
      panel.style.maxHeight = panel.scrollHeight + "px";
    }
  });
}

for (j = 0; j < sub_acc.length; j++) {
  sub_acc[j].addEventListener("click", function() {
    this.classList.toggle("sub-active");
    var sub_panel = this.nextElementSibling;
    if (sub_panel.style.maxHeight) {
      sub_panel.style.maxHeight = null;
    } else {
      sub_panel.style.maxHeight = sub_panel.scrollHeight + "px";
    }
  });
}

Правильно ли я понимаю. Вы хотите показать второй аккордеон и скрыть первый аккордеон, когда вы нажимаете на него? или вы хотите, чтобы первый аккордеон оставался открытым, когда открывается второй?

Crystal 16.03.2022 10:02
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2
1
39
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вот исправление в Javascript. Решение просто ищет активный аккордеон и снова устанавливает его максимальную высоту в логике щелчка субаккордеона.

const activeAccordion = document.getElementsByClassName("accordion active")[0]
var panel = activeAccordion.nextElementSibling;
panel.style.maxHeight = panel.scrollHeight + "px";

Полностью интегрирован с вашим Javascript

var acc = document.getElementsByClassName("accordion");
var i;
var sub_acc = document.getElementsByClassName("sub-accordion");
var j;


for (i = 0; i < acc.length; i++) {
  acc[i].addEventListener("click", function() {
    this.classList.toggle("active");
    var panel = this.nextElementSibling;
    if (panel.style.maxHeight) {
      panel.style.maxHeight = null;
    } else {
      panel.style.maxHeight = panel.scrollHeight + "px";
    }
  });
}

for (j = 0; j < sub_acc.length; j++) {
  sub_acc[j].addEventListener("click", function() {
    this.classList.toggle("sub-active");
    var sub_panel = this.nextElementSibling;
    if (sub_panel.style.maxHeight) {
      sub_panel.style.maxHeight = null;
    } else {
      sub_panel.style.maxHeight = sub_panel.scrollHeight + "px";
    }

    //The change is here
    const activeAccordion = document.getElementsByClassName("accordion active")[0]
    var panel = activeAccordion.nextElementSibling;
    panel.style.maxHeight = panel.scrollHeight + "px";
  });
}
.accordion {
  background-color: #eee;
  color: #444;
  cursor: pointer;
  padding: 18px;
  width: 100%;
  text-align: left;
  border: none;
  outline: none;
  transition: 0.4s;
}

.sub-accordion {
  background-color: rgb(181, 255, 191);
  color: #444;
  cursor: pointer;
  padding: 18px;
  width: 100%;
  text-align: center;
  border: none;
  outline: none;
  transition: 0.4s;
}

.active,
.accordion:hover {
  background-color: #ccc;
}

.sub-active,
.sub-accordion:hover {
  background-color: rgb(104, 255, 124);
  ;
}

.panel {
  padding: 0 18px;
  background-color: white;
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.2s ease-out;
}

.sub-panel {
  padding: 0 18px;
  background-color: lightblue;
  max-height: 0;
  overflow: hidden;
  transform: max-height 0.2s ease-out;
}

.container-wrapper {
  padding: 20pt;
}

.title-sections {
  font-size: 20px;
}
<div class = "container-wrapper"></div>
<button class = "accordion"><p class = "title-sections">Provisioning</p></button>
<div class = "panel">
  <button class = "sub-accordion">Set Variables</button>
  <div class = "sub-panel">
    <p>Lorem ipsum...</p>
  </div>
  <button class = "sub-accordion">Get Variables</button>
  <div class = "sub-panel">
    <p>Lorem ipsum...</p>
  </div>
  <button class = "sub-accordion">Reset</button>
  <div class = "sub-panel">
    <p>Lorem ipsum...</p>
  </div>
  <button class = "sub-accordion">Get Base Report</button>
  <div class = "sub-panel">
    <p>Lorem ipsum...</p>
  </div>
</div>

<button class = "accordion"><p class = "title-sections">Availability</p></button>
<div class = "panel">
  <p>Lorem ipsum...</p>
</div>

Для вашего HTML вам нужно обернуть все это в контейнер-оболочку, вот код для него:

<div class = "container-wrapper">
  <button class = "accordion">
    <p class = "title-sections">Provisioning</p>
  </button>
  <div class = "panel">
    <button class = "sub-accordion">Set Variables</button>
    <div class = "sub-panel">
      <p>Lorem ipsum...</p>
    </div>
    <button class = "sub-accordion">Get Variables</button>
    <div class = "sub-panel">
      <p>Lorem ipsum...</p>
    </div>
    <button class = "sub-accordion">Reset</button>
    <div class = "sub-panel">
      <p>Lorem ipsum...</p>
    </div>
    <button class = "sub-accordion">Get Base Report</button>
    <div class = "sub-panel">
      <p>Lorem ipsum...</p>
    </div>
  </div>

  <button class = "accordion">
    <p class = "title-sections">Availability</p>
  </button>
  <div class = "panel">
    <p>Lorem ipsum...</p>
  </div>
</div>

и для вашего CSS:

.container-wrapper {
  padding: 20pt;
  //add these two lines
  display: flex; 
  flex-direction: column;
}

Другие вопросы по теме