JavaScriptの .classList.toggle()
を使ってアコーディオンを作ります。
目次
.classList.toggle()
.classList.toggle()
は、classの追加・削除ができるプロパティで、名前の通り1つのスイッチでON/OFF(有効/無効)といった2つの状態の切り替えをおこなうことができます。
クリックやスクロール系のイベントと一緒に使って、例えば「一定量のスクロールでclassを付与して表示」「クリックで表示・非表示のclassを追加」など、いろんな用途で使えます。
.classList.toggle()を使ったアコーディオンサンプル
早速 .classList.toggle()
を使ったアコーディオンサンプルです。
あのイーハトーヴォのすきとおった風、夏でも底に冷たさをもつ青いそら、うつくしい森で飾られたモリーオ市、郊外のぎらぎらひかる草の波。あのイーハトーヴォのすきとおった風、夏でも底に冷たさをもつ青いそら、う
あのイーハトーヴォのすきとおった風、夏でも底に冷たさをもつ青いそら、うつくしい森で飾られたモリーオ市、郊外のぎらぎらひかる草の波。あのイーハトーヴォのすきとおった風、夏でも底に冷たさをもつ青いそら、う
あのイーハトーヴォのすきとおった風、夏でも底に冷たさをもつ青いそら、うつくしい森で飾られたモリーオ市、郊外のぎらぎらひかる草の波。あのイーハトーヴォのすきとおった風、夏でも底に冷たさをもつ青いそら、う
あのイーハトーヴォのすきとおった風、夏でも底に冷たさをもつ青いそら、うつくしい森で飾られたモリーオ市、郊外のぎらぎらひかる草の波。あのイーハトーヴォのすきとおった風、夏でも底に冷たさをもつ青いそら、う
至って普通のアコーディオンで、各見出し部分をクリックすると中身のコンテンツが表示・非表示で切り替わります。
アコーディオンサンプルのコード
アコーディオンのコードです。
HTMLは container
> accordion-group
> accordion
の階層です。
<div class="container">
<div class="accordion-group">
<div class="accordion">
<button class="accordion-header">accordion 1</button>
<div class="accordion-panel">
<p>あのイーハトーヴォのすきとおった風、夏でも底に冷たさをもつ青いそら、うつくしい森で飾られたモリーオ市、郊外のぎらぎらひかる草の波。あのイーハトーヴォのすきとおった風、夏でも底に冷たさをもつ青いそら、う</p>
</div>
</div>
<div class="accordion">
<button class="accordion-header">accordion 2</button>
<div class="accordion-panel">
<p>あのイーハトーヴォのすきとおった風、夏でも底に冷たさをもつ青いそら、うつくしい森で飾られたモリーオ市、郊外のぎらぎらひかる草の波。あのイーハトーヴォのすきとおった風、夏でも底に冷たさをもつ青いそら、う</p>
</div>
</div>
<div class="accordion">
<button class="accordion-header">accordion 3</button>
<div class="accordion-panel">
<p>あのイーハトーヴォのすきとおった風、夏でも底に冷たさをもつ青いそら、うつくしい森で飾られたモリーオ市、郊外のぎらぎらひかる草の波。あのイーハトーヴォのすきとおった風、夏でも底に冷たさをもつ青いそら、う</p>
</div>
</div>
<div class="accordion">
<button class="accordion-header">accordion 4</button>
<div class="accordion-panel">
<p>あのイーハトーヴォのすきとおった風、夏でも底に冷たさをもつ青いそら、うつくしい森で飾られたモリーオ市、郊外のぎらぎらひかる草の波。あのイーハトーヴォのすきとおった風、夏でも底に冷たさをもつ青いそら、う</p>
</div>
</div>
</div>
</div>
次にJavaScriptのコードですが、accordion-header
のボタンタグをクリックすると active のclassが toggle で追加され、.nextElementSibling
で次の要素に show のclassを追加して表示させます。
var acc = document.getElementsByClassName("accordion-header");
var i;
for (i = 0; i < acc.length; i++) {
acc[i].onclick = function(){
this.classList.toggle("active");
this.nextElementSibling.classList.toggle("show");
}
}
.previousElementSibling .nextElementSibling
.nextElementSibling
は「指定した要素の1つ後の要素を取得」するプロパティです。ちなみに、.previousElementSibling
は「指定した要素の1つ前の要素を取得」するプロパティです。
例えば、HTMLで以下のようなリストがあったとします。
<ul>
<li id="list1">リスト1</li>
<li id="list2">リスト2</li>
<li id="list3">リスト3</li>
</ul>
このリストに対して、それぞれElementSibling
のプロパティで取得すると以下のようになります。
const list2 = document.getElementById('list2');
console.log(list2.previousElementSibling);
// => <li id="list1">
console.log(list2.nextElementSibling);
// => <li id="list3">
このように、.previousElementSibling
.nextElementSibling
は、並列並びの要素がある時に使えるプロパティです。
この記事でのJavaScriptのコードでは、.nextElementSibling
を使っています。
CSS
JavaScriptのコードは、トグルでclassの付け替えだけ行うので、アコーディオンの見た目や表示はCSSでいじるようにしましょう。
以下は、このページのサンプルであてているCSSのコードです。
/* アコーディオン */
.container {
margin: 0 auto;
}
.accordion {
margin: 0;
}
button {
border: medium none;
}
.accordion-group {
border-left: 1px solid #ddd;
border-right: 1px solid #ddd;
border-top: 1px solid #ddd;
}
.accordion-header {
background-color: #fff;
border-bottom: 1px solid #ddd;
border-radius: 0;
color: #444;
cursor: pointer;
display: block;
font-weight: 600;
line-height: 1.25;
margin: 0;
padding: 14px 16px;
text-align: left;
text-decoration: none;
transition: all 0.2s ease 0s;
vertical-align: middle;
white-space: normal;
width: 100%;
position: relative;
}
.accordion-header.active,
.accordion-header:hover,
.accordion-header:focus {
background-color: #f1f1f1;
color: #444;
text-decoration: none;
}
.accordion-header:after {
content: '\25be';
font-size: 20px;
color: #777;
position: absolute;
top: 50%;
transform: translateY(-50%);
right: 15px;
transition: all 0.2s ease 0s;
}
.accordion-header.active:after {
transform: translateY(-50%) scale(1,-1);
}
/* with color */
.accordion-header.blue.active:after {
color: #fff;
}
.accordion-panel {
background-color: #fff;
display: none;
padding: 15px 20px;
overflow: hidden;
}
.accordion-panel.show {
border-bottom: 1px solid #ddd;
display: block;
}
.accordion .acc-panel p:last-child {
margin: 0;
}