こんにちは!Webディレクター兼エンジニアののせっち@nosecchi01です。
以前jQueryで矢印付きアコーディオンを実装する方法を解説しました。
お陰様で、当ブログ内では常にアクセス上位のページとなっています。
今回は、jQueryを使わずにJavascriptのみでアコーディオンメニューを実装する方法を解説します。
Javascriptに慣れている方にはクドい解説になっているかもしれませんが、
初心者の方向けに、かなり細かく解説をしていきます!
複数展開
早速コードペンで見てみましょう!
See the Pen Accordion (javascript ver) by Yuki Nose (@yukinouz1) on CodePen.
意外とjavascriptのコード量が少なく実現できていることがわかります。
Javascriptの解説
HTML, CSSは基本的な事しか書いていないので、主にJavascriptを解説していきます。
一点だけ、この記事内の解説では、
- クリックする要素:javascript : ’.js-accordion-title’ css: accordion__title
- 展開する要素:’.accordion__content’
となっています。これだけ頭に入れてください。
Javascriptコード全体像
まず、Javascriptのコード全体を見てみましょう!
document.addEventListener("DOMContentLoaded",() => {
const title = document.querySelectorAll('.js-accordion-title');
for (let i = 0; i < title.length; i++){
let titleEach = title[i];
let content = titleEach.nextElementSibling;
titleEach.addEventListener('click', () => {
titleEach.classList.toggle('is-active');
content.classList.toggle('is-open');
});
}
});
大まかにはやっていることは下記の2つです!
- ‘.js-accordion-title’ = クリックする要素を取得。
- for分で要素一つ一つに対して、クリックイベント。
一つずつ見ていきましょう。
‘.js-accordion-title’ → クリックする要素を取得。
const title = document.querySelectorAll('.js-accordion-title');
document.querySelectorAllでクリックする要素である、’.js-accordion-title’を取得します。
クリックする要素は複数あるので、querySelectorAllを使います。
Document.querySelectorAll() MDN
https://developer.mozilla.org/ja/docs/Web/API/Document/querySelectorAll
for分で要素一つ一つに対して、クリックイベント。
for (let i = 0; i < title.length; i++){
let titleEach = title[i];
let content = titleEach.nextElementSibling;
titleEach.addEventListener('click', () => {
titleEach.classList.toggle('is-active');
content.classList.toggle('is-open');
});
}
・title.lengthでtitleの数分繰り返すということです。
・let titleEach = title[i] の部分でtitleのindexを一つずつ代入しています。
・.nextElementSiblingは隣の要素を指しますので、’accordion__content’になります。
具体的には下記です。
<h4 class="accordion__title js-accordion-title">Accordion Title 1</h4> <!-- titleEach -->
<div class="accordion__content">Accordion Content 1</div> <!-- nextElementSibling -->
titleEach.addEventListener('click', () => {
// この中の処理を行う
});
・titleEachをクリックしたら下記の処理を行いなさい。
titleEach.classList.toggle('is-active');
content.classList.toggle('is-open');
・titleEach.classList.toggle(‘is-active’); で’accordion__title’に’is-active’ クラスを付け外し。
・content.classList.toggle(‘is-open’); で’accordion__content’クラスを付け外しします。
toggleを使うことで、該当のクラスが無ければaddClass、あればremoveClassを行なってくれます。
少し違う書き方
コメントアウトにしていますが、下記でもOKです。
const title = document.querySelectorAll('.js-accordion-title');
function toggle(){
const content = this.nextElementSibling;
this.classList.toggle('is-active');
content.classList.toggle('is-open');
}
for (let i = 0; i < title.length; i++){
title[i].addEventListener('click', toggle)
}
こちらの場合は、toggle関数を定義しておいて、addEventListenerで呼び出す形です。
こちらの方が、順序がハッキリしてわかりやすいかもしれませんね!
考え方は同じなので、どちらでもOKです!
一つ開いたら他は閉じる
少し複雑になります。
See the Pen Accordion Single (javascript ver) by Yuki Nose (@yukinouz1) on CodePen.
Javascriptコード全体像
const accSingleTriggers = document.querySelectorAll('.js-acc-single-trigger');
accSingleTriggers.forEach(trigger => trigger.addEventListener('click', toggleAccordion));
function toggleAccordion() {
const items = document.querySelectorAll('.js-acc-item');
const thisItem = this.parentNode;
items.forEach(item => {
if (thisItem == item) {
thisItem.classList.toggle('is-open');
return;
}
item.classList.remove('is-open');
});
}
jsの構成は下記のようになっています。
一つだけ開くアコーディオンの場合は、クリックした要素の親要素(prarentNode)にis-openクラスを付けます。
- クリックした要素の親と、一致したときのみis-openクラスを付与
- それ以外の要素はis-openクラスを外す
という構成です。
最初の要素は開いておく
こちらは2行追加するだけです!
See the Pen Accordion open first content(Javascript ver) by Yuki Nose (@yukinouz1) on CodePen.
Javascriptコード全体像
const accSingle = document.querySelector('.js-acc-single');
const items = accSingle.querySelectorAll('.js-acc-item');
const accSingleTriggers = accSingle.querySelectorAll('.js-acc-single-trigger');
// 最初の要素を開いておく
const firstChild = accSingle.firstElementChild;
firstChild.classList.add('is-open');
accSingleTriggers.forEach(trigger => trigger.addEventListener('click', toggleAccordion));
function toggleAccordion() {
const thisItem = this.parentNode;
items.forEach(item => {
if (thisItem == item) {
thisItem.classList.toggle('is-open');
return;
}
item.classList.remove('is-open');
});
}
firstElementChildでアコーディオンの最初の要素を取得しておき、is-openクラスをつけておくだけです。
これは簡単ですね!
Javascriptのおすすめ勉強法
学習サイトとしてはドットインストールがオススメです。
僕は基本Progate派なのですが、Javascriptに関してはドットインスールが最適です。
- とにかく講座数が多い(課金は必須)
- 実際にアプリを作りながら学べるので実践に近い
- よく使う技術は何度も出てくるため、自然と覚えられる
ドットインストールは、「ん?それ習ってないぞ・・・?」と言うのがいきなり出てきたりするのが難点ではありますが、Javascriptに関しては、レッスン数が多いため、数をこなして覚えていくのがいいと思います。
Javascriptのオススメ書籍
Javascriptでオススメの書籍はこちらです。
正直内容はツマラナイのですが・・・。
タイトル通り「コードレシピ集」となっており、辞書的に使うのに最適です!
上記のドットインストールと合わせて使うことで、内容を補完し合えるのでオススメです。
まとめ
- バニラjsでも意外と少ないコードで書く事ができる
- jQueryは便利