Как сделать аккордеон на JS

Рейтинг: -1Ответов: 2Опубликовано: 10.05.2023

Делаю аккордеон, логику его работы такая: при наведении на родительский элемент, появляется дочерний.

Вкладок аккордеона несколько.

    <div class="catalog-content">
        <ul>
            <li class="accordion-parent" data-id="menu-1">Текст родительского элемента</li>
            <li class="accordion-parent" data-id="menu-2">Текст родительского элемента</li>
            <li class="accordion-parent" data-id="menu-3">Текст родительского элемента</li>
        </ul>
    </div>
    <div class="subcatalog-content">
        <ul class="accordion-child" data-id="menu-1" style="display: none;">
            <li>Произвольный текст дочернего элемента</li>
            <li>Произвольный текст дочернего элемента</li>
        </ul>
        <ul class="accordion-child" data-id="menu-2" style="display: none;">
            <li>Произвольный текст дочернего элемента</li>
            <li>Произвольный текст дочернего элемента</li>
        </ul>
        <ul class="accordion-child" data-id="menu-3" style="display: none;">
            <li>Произвольный текст дочернего элемента</li>
            <li>Произвольный текст дочернего элемента</li>
        </ul>
    </div>

    <style>
       .block {
      display: block!important;
       }
</style>

Я накинул свой вариант, но оно не работает

var accordIndex = document.querySelector('.catalog-content ul').childNodes.length;

for (i = 1; i < accordIndex+1; i++) {
  document.querySelector('.accordion-parent[data-id="menu-'+i+'"]').addEventListener('mouseover', function() {
  document.querySelector('.accordion-child[data-id="menu-'+i+'"]').classList.add('block'); 
});
};

Подскажите, пожалуйста, что можно сделать, какой логикой руководствоваться?) Спасибо!

Ответы

▲ 0Принят

какой логикой руководствоваться?

Вот так можно такое реализовать...

document.querySelector('.catalog-content').addEventListener('mouseover', e => {
  const o = e.target
  if (!o.classList.contains('accordion-parent')) return
  const v = o.dataset.id
  const oa = document.querySelector('.subcatalog-content .on')
  if (oa) oa.classList.remove('on')
  document.querySelector(`.subcatalog-content [data-id="${v}"]`).classList.add('on')
})
.subcatalog-content .accordion-child {
  display: none;
}
.subcatalog-content .accordion-child.on {
  display: block;
}
<div class="catalog-content">
  <ul>
    <li class="accordion-parent" data-id="menu-1">Текст родительского элемента 1</li>
    <li class="accordion-parent" data-id="menu-2">Текст родительского элемента 2</li>
    <li class="accordion-parent" data-id="menu-3">Текст родительского элемента 3</li>
  </ul>
</div>
<div class="subcatalog-content">
  <ul class="accordion-child" data-id="menu-1">
    <li>Произвольный текст дочернего элемента 1</li>
    <li>Произвольный текст дочернего элемента 1</li>
  </ul>
  <ul class="accordion-child" data-id="menu-2">
    <li>Произвольный текст дочернего элемента 2</li>
    <li>Произвольный текст дочернего элемента 2</li>
  </ul>
  <ul class="accordion-child" data-id="menu-3">
    <li>Произвольный текст дочернего элемента 3</li>
    <li>Произвольный текст дочернего элемента 3</li>
  </ul>
</div>

▲ 1

А не легче использовать псевдоклассы от CSS вместо событие JS? Вот пример кода используя только CSS

const childs = document.querySelectorAll('.child >li');

for (let child of childs) {
  child.addEventListener('click', () => {
    console.log('click child');
  })
}
.parent>li:hover .child {
  display: block;
}

.child {
  display: none;
}
<div class="accordion">
  <ul class="parent">
    <li>Parent
      <ul class="child">
        <li>Child</li>
        <li>Child</li>
      </ul>
    </li>
    <li>Parent
      <ul class="child">
        <li>Child</li>
        <li>Child</li>
      </ul>
    </li>
    <li>Parent
      <ul class="child">
        <li>Child</li>
        <li>Child</li>
      </ul>
    </li>
    <li>Parent
      <ul class="child">
        <li>Child</li>
        <li>Child</li>
      </ul>
    </li>
  </ul>
</div>