【jQuery】tableにアコーディオンを実装&兄弟要素内の子要素を指定する
Photo by Valery Sysoev on Unsplash
こんにちは。E-kan株式会社の岡田です。
先日、20行以上あるtableタグで組まれているお客様の社内用データベース管理ページの改修を行ったのですが、地味に苦労したので備忘録。
やりたいこと
- デフォルトは最初の2行を見出しとして表示させ、残りの行はアコーディオンで折りたたむ
- tableの下に「詳細を表示する」というテキストを置き、クリックするとアコーディオンが開き、「詳細を閉じる」という文言に変える
- アコーディオンを閉じたら見出し行の位置に戻る
- テーブルは複数あるので、個別にアコーディオンが開くようにする
<section class="accordion">
<table>
<thead>
<tr>
<th>タイトル1</th>
<td>本文1本文1</td>
</tr>
<tr>
<th>タイトル2</th>
<td>本文2本文2</td>
</tr>
</thead>
<tbody class="accordion_body">
<tr>
<th>タイトル3</th>
<td>本文3本文3</td>
</tr>
〜〜〜 略 〜〜〜
<tr>
<th>タイトル20</th>
<td>本文20本文20</td>
</tr>
</tbody>
</table>
<span class="more">詳細を表示する</span>
</section>
jQuery
$(function(){
//アコーディオン部分を非表示にしておく
$('.accordion_body').hide();
//.more をクリックしたら実行
$('.more').on('click',function(){
//クリックした要素の兄弟要素内の子要素(開閉させたい箇所)を変数に格納する
var acBody = $(this).siblings(".accordion").children(".accordion_body")
if(acBody.is(':hidden')){ //アコーディオンが非表示だったら実行する内容
acBody.show(); //アコーディオンを表示させる
$(this).addClass('active').text('詳細を非表示にする'); //テキストを変えてclassを付与
} else { //アコーディオンが表示されていたら実行する内容
acBody.hide(); //アコーディオンを非表示にする
$(this).removeClass('active').text('詳細を表示する'); //テキストを戻してclassを取る
var offset = $(this).parent().offset().top; //ページ上部から親要素の頭の位置までを変数に格納
$(window).scrollTop(offset); //スクロール位置を見出し行に戻す
}
});
});
こんな感じの、クリックした直下の要素を開閉させる単純なアコーディオンなら
<dl>
<dt class="more">タイトル</dt>
<dd class="accordion_body">本文</dd>
</dl>
nextとslideToggleを使ってサクッと実装出来るのですが、
$('.more').click(function(){
$(this).toggleClass('active');
$(this).next('.accordion_body').slideToggle();
});
今回は既存のtable要素の一部をアコーディオンとして開閉させたいという事と、開閉のトリガーになる要素が兄弟要素ということで地味に苦労しました。(siblingsメソッドを初めて知った。勉強になった。)
あと、最初はアコーディオンをslideDown・slideUpにしていたのですが何故かアニメーションにならず、調べたところtableタグではアニメーションをサポートしていないとのことでした。
参考
https://www.web-dev-qa-db-ja.com/ja/jquery/%E3%83%86%E3%83%BC%E3%83%96%E3%83%AB%E8%A1%8C%E3%81%A7slidedown%EF%BC%88%E3%81%BE%E3%81%9F%E3%81%AFshow%EF%BC%89%E9%96%A2%E6%95%B0%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95%E3%81%AF%EF%BC%9F/958218212/
まぁ、最近はtableを使うこともそんなに無いかと思いますが、アニメーションさせたいのなら最初からtableで組んじゃだめということですね。