Отображение блока и скрытие блока по нажатию одной кнопки
Пишу впервые и очень надеюсь получить помощь. У меня есть блок. Цель блока, получение ответа на часто задаваемые вопросы. В этом блоке написан сам вопрос и есть иконка в виде знака "+" При нажатии на эту иконку появляется блок с ответом на данный вопрос. Все работает, однако если добавить вторые два блока(вопрос + ответ), то при нажатии на один из плюсов открывается два блока с ответами.
const faqBtns = document.querySelectorAll(".faq-fi");
const faqBodys = document.querySelectorAll(".faq-body");
const faqBtn = document.querySelector(".faq-fi");
const faqBody = document.querySelector(".faq-body");
faqBtns.forEach(faqBtn => {
faqBtn.addEventListener("click", () => {
faqBodys.forEach(faqBody => {
if (faqBody.style.display == "none") {
faqBtn.style.transform = "rotate(90deg)";
faqBody.style.display = "block";
} else {
faqBtn.style.transform = "rotate(45deg)";
faqBody.style.display = "none";
}
})
})
})
<section class="faq-box">
<div class="faq-header">
<h4 class="faq-heading">Цена на товар указана с учетом НДС?</h4>
<i class="fi fi-rr-cross faq-fi"></i>
</div>
<div class="faq-body">
<p class="faq-text">Цена указана уже с НДС</p>
</div>
<div class="faq-header">
<h4 class="faq-heading">Как рассчитывается стоимость доставки?</h4>
<i class="fi fi-rr-cross faq-fi"></i>
</div>
<div class="faq-body">
<p class="faq-text">Стоимость доставки. Бла бла бла.</p>
</div>
</section>
При нажатии на один из плюсов открывается два блока с ответами.
Ответы (2 шт):
faqBtn.addEventListener("click", () => {
faqBodys.forEach(faqBody => {
...
})
})
У вас в коде указано, что при клике на иконку нужно по всем .faq-body пройтись, поэтому у вас открывается все. Если вы хотите сохранить текущую разметку, вам необходимо обращаться только к элементу с таким же индексом массиве faqBodys, как у текущего faqBtn.
Пример, как это можно сделать:
const faqBtns = document.querySelectorAll(".faq-fi");
const faqBodys = document.querySelectorAll(".faq-body");
faqBtns.forEach((faqBtn, faqBtnKey) => {
faqBtn.addEventListener("click", function() {
if (faqBodys[faqBtnKey].style.display == "none") {
this.style.transform = "rotate(45deg)";
faqBodys[faqBtnKey].style.display = "block";
} else {
this.style.transform = "rotate(0)";
faqBodys[faqBtnKey].style.display = "none";
}
})
})
<section class="faq-box">
<div class="faq-header">
<h4 class="faq-heading">Цена на товар указана с учетом НДС?</h4>
<i class="fi fi-rr-cross faq-fi">+</i>
</div>
<div class="faq-body">
<p class="faq-text">Цена указана уже с НДС</p>
</div>
<div class="faq-header">
<h4 class="faq-heading">Как рассчитывается стоимость доставки?</h4>
<i class="fi fi-rr-cross faq-fi">+</i>
</div>
<div class="faq-body">
<p class="faq-text">Стоимость доставки. Бла бла бла.</p>
</div>
</section>
Предложу вот такой вариант решения с использованием делегирования событий... Обработчик один, на родителе. Именно он и решает задачу "Вкл/Выкл" нужного элемента.
// навешиваю обработчик клика на родительский элемент
document.querySelector(".faq-box").addEventListener("click", e => {
// определяю элемент на котором произошло событие клика
let o = e.target
// если это не тот элемент - заканчиваю обработку
if (!o.closest('.faq-fi')) return
// определяю нужного мне родителя
o = o.closest('.faq-header')
// определяю следующий за ним элемент
o = o.nextElementSibling
// добавляю или удаляю класс on
o.classList.toggle('on')
})
.faq-body {
display: none;
}
.faq-body.on {
display: block;
}
<section class="faq-box">
<div class="faq-header">
<h4 class="faq-heading">Цена на товар указана с учетом НДС?</h4>
<i class="fi fi-rr-cross faq-fi">+</i>
</div>
<div class="faq-body">
<p class="faq-text">Цена указана уже с НДС</p>
</div>
<div class="faq-header">
<h4 class="faq-heading">Как рассчитывается стоимость доставки?</h4>
<i class="fi fi-rr-cross faq-fi">+</i>
</div>
<div class="faq-body">
<p class="faq-text">Стоимость доставки. Бла бла бла.</p>
</div>
</section>