・はじめに
JavaScriptとCSSを利用して簡単なアコーディオンメニューを作ったのでそれを記録する記事です。もっとこうすればいいよなどのアドバイスがあればよろしくお願いいたします。
・コードと解説
今回作ったアコーディングメニューはcheckboxを利用したもので、1つ開くと他が閉じる仕様ではなく、開こうと思えばすべて開くことができるようになっています。
・処理の流れ
CSSでクラス名を指定してメニューの内容を非表示にする⇒JavaScriptでチェックボックスをクリックしたとき、チェックボックスがtrue状態に変われば、CSSの非表示のクラス名を削除して表示状態に、反対にfalse状態に変わればCSSの非表示クラス名を追加させて非表示状態にする
という流れで行います。
HTML
<label>
<input type="checkbox" data-checkbox="0">メニュー1
</label>
<p class="content" data-content="0">メニュー1の内容です。</p>
<label>
<input type="checkbox" data-checkbox="1">メニュー2
</label>
<p class="content" data-content="1">メニュー2の内容です。</p>
CSS
.content {
/*メニュー内容の表示を非表示にする*/
display: none;
}
input[type="checkbox"] {
/*チェックボックスのチェックマークを消す。作成時はわかりやすいようにつけておいた方がいいかもしれません*/
display: none;
}
JavaScript
(()=> {
const $doc = document;
const $checkbox = $doc.querySelectorAll('[data-checkbox]');
const checkboxLen = $checkbox.length;
const $content = $doc.querySelectorAll('[data-content]');
const CONTENT_CLASS = 'content';
const changeClassName = (e) => {
const $this = e.target;
const targetVal = $this.dataset.checkbox;
//クリックされたチェックボックスを指定
const $designatedCheckbox = $checkbox[targetVal];
$designatedCheckbox.addEventListener("change", ()=> {
//もしチェックに変化したら
if($designatedCheckbox.checked) {
//contentクラスを削除し、内容を表示させる
$content[targetVal].classList.remove(CONTENT_CLASS);
//もしチェックが消されたら
} else {
//contentクラスを追加し、内容を非表示にさせる
$content[targetVal].classList.add(CONTENT_CLASS);
}
});
};
//ループ文を使って発火させる(スコープによりどこのcheckboxが押されたかを特定できないのでこのような表現になっている)
let index = 0;
while(index < checkboxLen) {
$checkbox[index].addEventListener('click', (e) => changeClassName(e));
index++;
}
})();
・おわりに
これで完成です。デザイン面のコーディングは特にしていないのでそちらはご自由にお願いします。