Ракскрытие списка JS

Необходимо сделать чтобы в списке ul при нажатии на h4 открывались все p. Сделал через querySelectorAll. Но проблема появилась, он начал открывать все списки с p. Помогите пжл

let btn = document.querySelectorAll(".list > div > h3");
btn.forEach(btn => btn.addEventListener("click", () => { btnClick(btn.parentElement) }));
function btnClick(btn) {
    btn.querySelector('ul').classList.toggle("show");
};
let btnDiv = document.querySelectorAll(".list > div > ul > li > div > h4");
btnDiv.forEach(btnDiv => btnDiv.addEventListener("click", () => { divClick(btnDiv.parentElement) }));
function divClick(btnDiv) {
    btnDiv.querySelector("p").classList.toggle("show");
};
ul {
    display: none;
}
ul > li > div > p {
    display: none;
}
.show {
    display: block;
}
.list {
    align-content: center ;
}
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="css/main.css">
</head>

<body>

    <div class="list">
        <div>
            <h3> Кафедра 1</h3>

            <ul>
                <li>
                    Файл 1
                </li>
                <li>
                    Файл 2
                </li>
                <li>
                    <div>
                        <h4>Папка 1</h4>
                        <p>Файл 1</p>
                        <p>Файл 2</p>
                    </div>
                </li>
                <li>
                    <div>
                        <h4>Папка 2</h4>
                        <p>Файл 1</p>
                        <p>Файл 2</p>
                    </div>
                </li>
            </ul>
        </div>
        <div>
            <h3> Кафедра 2</h3>

            <ul>
                <li>
                    Файл 1
                </li>
                <li>
                    Файл 2
                </li>
                <li>
                    <div>
                        <h4>Папка 1 </h4>
                        <p>Файл 1</p>
                        <p>Файл 2</p>
                    </div>
                </li>
                <li>
                    <div>
                        <h4>Папка 2 </h4>
                        <p>Файл 1</p>
                        <p>Файл 2</p>

                    </div>
                </li>
            </ul>
        </div>
        <div>
            <h3> Кафедра 3</h3>

            <ul>
                <li>
                    Файл 1
                </li>
                <li>
                    Файл 2
                </li>
                <li>
                    <div>
                        <h4>Папка 1 </h4>
                        <p>Файл 1</p>
                        <p>Файл 2</p>
                    </div>
                </li>
                <li>
                    <div>
                        <h4>Папка 2 </h4>
                        <p>Файл 1</p>
                        <p>Файл 2</p>

                    </div>
                </li>
            </ul>
        </div>
        <div>
            <h3> Кафедра 4</h3>

            <ul>
                <li>
                    Файл 1
                </li>
                <li>
                    Файл 2
                </li>
                <li>
                    <div>
                        <h4>Папка 1 </h4>
                        <p>Файл 1</p>
                        <p>Файл 2</p>
                    </div>
                </li>
                <li>
                    <div>
                        <h4>Папка 2 </h4>
                        <p>Файл 1</p>
                        <p>Файл 2</p>

                    </div>
                </li>
            </ul>
        </div>
    </div>

    <script src="main.js"></script>
</body>

</html>


Ответы (2 шт):

Автор решения: Armen

можно конечно исправить но более красивое и понятное и нормальное решение получше будет

let list = document.querySelector('.list');

const click = (e) => {
    switch(e.target.tagName){
        case 'H3':
            e.target.nextElementSibling.classList.toggle('show')
            break
        case 'H4':
            let next = e.target
            while(next = next.nextElementSibling){
                next.classList.toggle('show') 
            }
            break
        default:
            break
    }
}

list.addEventListener('click',click)
ul {
  display: none;
}
ul > li > div > p {
  display: none;
}
.show {
  display: block;
}
.list {
  align-content: center ;
}
h4{
  border: 1px solid red;
}
  <div class="list">
    <div>
        <h3> Кафедра 1</h3>
        <ul>
            <li>
                Файл 1
            </li>
            <li>
                Файл 2
            </li>
            <li>
                <div>
                    <h4>Папка 1</h4>
                    <p>Файл 1</p>
                    <p>Файл 2</p>
                    <p>Файл 3</p>
                    <p>Файл 4</p>
                    <p>Файл 5</p>
                    <p>Файл 6</p>
                </div>
            </li>
            <li>
                <div>
                    <h4>Папка 2</h4>
                    <p>Файл 1</p>
                    <p>Файл 2</p>
                </div>
            </li>
        </ul>
    </div>
    <div>
        <h3> Кафедра 2</h3>

        <ul>
            <li>
                Файл 1
            </li>
            <li>
                Файл 2
            </li>
            <li>
                <div>
                    <h4>Папка 1 </h4>
                    <p>Файл 1</p>
                    <p>Файл 2</p>
                </div>
            </li>
            <li>
                <div>
                    <h4>Папка 2 </h4>
                    <p>Файл 1</p>
                    <p>Файл 2</p>

                </div>
            </li>
        </ul>
    </div>
    <div>
        <h3> Кафедра 3</h3>

        <ul>
            <li>
                Файл 1
            </li>
            <li>
                Файл 2
            </li>
            <li>
                <div>
                    <h4>Папка 1 </h4>
                    <p>Файл 1</p>
                    <p>Файл 2</p>
                </div>
            </li>
            <li>
                <div>
                    <h4>Папка 2 </h4>
                    <p>Файл 1</p>
                    <p>Файл 2</p>

                </div>
            </li>
        </ul>
    </div>
    <div>
        <h3> Кафедра 4</h3>

        <ul>
            <li>
                Файл 1
            </li>
            <li>
                Файл 2
            </li>
            <li>
                <div>
                    <h4>Папка 1 </h4>
                    <p>Файл 1</p>
                    <p>Файл 2</p>
                </div>
            </li>
            <li>
                <div>
                    <h4>Папка 2 </h4>
                    <p>Файл 1</p>
                    <p>Файл 2</p>

                </div>
            </li>
        </ul>
    </div>
</div>

→ Ссылка
Автор решения: savage

let nameMenu = document.querySelectorAll('.menu__name');
let menu = document.querySelectorAll('.menu');
for (let i = 0; i < nameMenu.length; i++) {
    nameMenu[i].addEventListener('click', function () {
        if (menu[i].contains(nameMenu[i])) {
            let child = menu[i].children;
            for (let b = 0; b < child.length; b++) {
                child[b].classList.toggle('show')
            }
        }
    })
}
.menu > ul,
li {
  display: none;
}
.show {
  display: block !important;
}
<ul class="menu">
        <h1 class="menu__name">папка 1</h1>
        <li class="menu__item">1</li>
        <li class="menu__item">2</li>
        <li class="menu__item">3</li>
        <ul class="menu">
            <h1 class="menu__name">папка 2</h1>
            <li class="menu__item">4</li>
            <li class="menu__item">5</li>
            <li class="menu__item">6</li>
        </ul>
    </ul>

→ Ссылка