サイト制作時、FAQ の項目の回答内容を非表示にしておいて、ボタンをクリックすると回答内容が表示できるようにするには、どうすればよいのでしょうか?

今回は、質問内容をクリックすると、回答内容が表示・非表示する方法を紹介します。

まずは、質問と回答を作ります。

<div class="faq">
  <div class="question">
    <p>好きな食べ物は何ですか?</p>
  </div>
  <div class="answer">
    <p>鳥の唐揚げです。</p>
  </div>
</div>

<div class="faq">
  <div class="question">
    <p>朝食は、パン派ですか?ご飯派ですか?</p>
  </div>
  <div class="answer">
    <p>パン派です。</p>
  </div>
</div>
.faq {
  margin-top: 4rem;
  margin-bottom: 4rem;
  background-color: beige;
  width: 30rem;
  padding: 1rem 2rem;
  border-radius: 1rem;
  box-shadow: 4px 4px 4px rgba(0, 0, 0, 0.4);
}
.answer {
  border-top: 1px solid rgba(0, 0, 0, 0.2);
}

image2

表示・非表示のボタンを作成します。

ボタンは、Google の Material Icons を使用しています。

<div class="question">
  <p>好きな食べ物は何ですか?</p>
  <button class="question-button">
    <span class="material-icons-outlined more"> expand_more </span>
    <span class="material-icons-outlined less"> expand_less </span>
  </button>
</div>
.question button {
  border: none;
  background-color: transparent;
  cursor: pointer;
}

image3

初めは回答内容と上矢印ボタンを表示しないようにしたいので、それぞれ、display: none;で設定します。

.answer {
  display: none;
}
.less {
  display: none;
}

image4

回答が表示している時、回答内容と上矢印ボタンを表示にして、下矢印ボタンを非表示にします。

回答内容と上矢印ボタンには、display: block; 下矢印ボタンには、display: none;を上書きします。

JavaScript で操作するために、新たに.show-answer クラスを設けて、設定します。

.show-answer .answer {
  display: block;
}
.show-answer .less {
  display: block;
}
.show-answer .more {
  display: none;
}

JavaScript でやりたいことは、

  • 複数の FAQ に対応する。
  • ボタンを指定する。
  • 回答内容が非表示時にボタンをクリックすると、回答内容と上矢印ボタンが表示する。
  • 回答内容が非表示時にボタンをクリックすると、下矢印ボタンが非表示になる。
  • 回答内容が表示時にボタンをクリックすると、回答内容と上矢印ボタンが非表示になる。
  • 回答内容が非表示時にボタンをクリックすると、下矢印ボタンが表示する。
  • どちらかの回答内容が開いた時、他の回答内容が閉じる。

です。

まず、querySelectorAllで複数の FAQ を指定します。

const faq = document.querySelectorAll(".faq")

次に、forEach で、それぞれの FAQ を呼び出します。

faq.forEach(function (question) {})

console.log で確認すると、

faq.forEach(function (question) {
  console.log(question)
})

image5

それぞれの FAQ を呼び出すことができました。

次は、querySelectorでボタンを指定します。

const button = question.querySelector(".question-button")

addEventListenerでボタンをクリックすると、何らかのアクションが起こるようにします。

button.addEventListener("click", function () {})

classList.toggleshow-answerクラスの有無を切り替えます。

button.addEventListener("click", function () {
  question.classList.toggle("show-answer")
})

動作を確認すると、

image6

表示・非表示がうまくいきました。

最後に、どちらかの回答内容が開くと、他の回答内容が閉じるようにします。

クリックする度にforEachでそれぞれ FAQ を呼び出します。

button.addEventListener("click", function () {
  faq.forEach(function (eachQuestion) {})
  question.classList.toggle("show-answer")
})

クリックした FAQ(question)と呼び出した FAQ(eachQuestion)が同じでない場合、show-answerクラスを削除します。

コードは以下の通りです。

button.addEventListener("click", function () {
  faq.forEach(function (eachQuestion) {
    if (eachQuestion !== question) {
      eachQuestion.classList.remove("show-answer")
    }
  })
  question.classList.toggle("show-answer")
})

動作を確認すると、

image7

片方の回答内容が表示したら、他の回答内容が非表示になりました。

JavaScript の全文です。

const faq = document.querySelectorAll(".faq")

faq.forEach(function (question) {
  const button = question.querySelector(".question-button")

  button.addEventListener("click", function () {
    faq.forEach(function (eachQuestion) {
      if (eachQuestion !== question) {
        eachQuestion.classList.remove("show-answer")
      }
    })
    question.classList.toggle("show-answer")
  })
})

FAQ 周りがスッキリしてみやすくなりますので、ぜひ使ってみてください。

ブログ一覧