Значок переключения аккордеона не работает должным образом

#javascript #html #css

#javascript #HTML #css

Вопрос:

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

Я попытался добавить минус / плюс let и попытался добавить для него display.styles. Но это кажется действительно глючным и не работает должным образом. Как я могу правильно это настроить? И это работает только для первого элемента, а не для всех.

 const tabs = document.querySelectorAll(".faq__tab").forEach(button => {
  button.addEventListener("click", () => {
    const tabsContent = button.nextElementSibling;
    button.classList.toggle('active-faq');
    let minus = document.querySelector(".plus")
    let plus = document.querySelector(".minus")

    if (button.classList.contains('active-faq')) {
      tabsContent.style.maxHeight = tabsContent.scrollHeight   'px';
      plus.style.display = 'none';
      minus.style.display = 'flex';
    } else {
      tabsContent.style.maxHeight = 0;
      minus.style.display = 'none';
      plus.style.display = 'flex';
    }
  })
});  
 .plus {
  padding-left: 10px;
}

.minus {
  padding-left: 10px;
  display: none;
}

.faq__panel {
  max-height: 0px;
  overflow: hidden;
}  
 <button class="faq__tab">Question
 <img src='img/plus.svg' alt="Show" class="plus">
 <img src='img/minus-svg.png' alt="Hide" class="minus">
</button>
<div class="faq__panel">
  <p>Answerr
  </p>
</div>  

Ответ №1:

Вероятно, вам нужно использовать inline-flex вместо flex :

 const tabs = document.querySelectorAll(".faq__tab").forEach(button => {
  button.addEventListener("click", () => {
    const tabsContent = button.nextElementSibling;
    button.classList.toggle('active-faq');
    let minus = button.querySelector(".plus");//instead of document use button to target the corresponding element
    let plus = button.querySelector(".minus");//instead of document use button to target the corresponding element

    if (button.classList.contains('active-faq')) {
      tabsContent.style.maxHeight = tabsContent.scrollHeight   'px';   
      minus.style.display = 'none';
      plus.style.display = 'inline-flex';
    } else {
      tabsContent.style.maxHeight = 0;
      plus.style.display = 'none';
      minus.style.display = 'inline-flex';
    }
  })
});  
 .plus {
  padding-left: 10px;
}

.minus {
  padding-left: 10px;
  display: none;
}
.faq__panel {
  max-height: 0px;
  overflow: hidden;
}  
 <button class="faq__tab">Question1
  <img src='img/plus.svg' alt="Show" class="plus">
  <img src='img/minus-svg.png' alt="Hide" class="minus">
</button>
<div class="faq__panel">
  <p>Answer1</p>
</div>

<button class="faq__tab">Question2
  <img src='img/plus.svg' alt="Show" class="plus">
  <img src='img/minus-svg.png' alt="Hide" class="minus">
</button>
<div class="faq__panel">
  <p>Answer2</p>
</div>  

Комментарии:

1. Все еще не работает. Мне не хватало одного стиля css для faq__panel, можете ли вы снова просмотреть исходное сообщение?

2. По-прежнему не работает, потому что после первого нажатия по-прежнему отображается надпись «Показать», на этом этапе уже должен быть скрытый текст.

3. @Dave, исправил это, заменив блок скрыть / показать код в блоке if / else, пожалуйста, проверьте сейчас 🙂

4. Спасибо, работает. Теперь у меня есть еще 1 проблема: всякий раз, когда я добавляю дополнительные вкладки faq__, эффект javascript работает только для первого элемента, может быть, вы знаете, почему?

5. @Dave, для этого вместо document object тебе нужно искать элемент ( .plus , .minus ) из текущей button переменной. Обновил ответ другим блоком, пожалуйста, проверьте 🙂

Ответ №2:

Проблема в том, что вы устанавливаете отображение изображения flex , либо указываете кнопку faq__tab display: flex в файле css, либо устанавливаете display: inline значение images

 if (button.classList.contains('active-faq')) {
  tabsContent.style.maxHeight = tabsContent.scrollHeight   'px';
   plus.style.display = 'none';
  minus.style.display = 'inline';
} else {
  tabsContent.style.maxHeight = 0;
  minus.style.display = 'none';
  plus.style.display = 'inline';
}