jQueryのslideToggle()
はすごく便利ですが、頼りすぎるとエンジニア強度が下がってしまいます。
下がらないように、素のJavaScriptでも、アコーディオンを作ってみましょう。
サンプルコード
こんな感じで作ってみました。
const accordion = (
// 初期値
{
target = 'js-ac',
btn = 'js-ac_btn',
content = 'js-ac_content',
speed = 1.5,
cssEase = 'ease-out'
} = {}
) => {
const TARGET = document.getElementsByClassName(target);
const TARGET_LENGTH = TARGET.length;
for (let i = 0; i < TARGET_LENGTH; i++) {
let isShow = false;
const CURRENT_TARGET = TARGET[i];
const BTN = CURRENT_TARGET.getElementsByClassName(btn)[0];
const CONTENT = CURRENT_TARGET.getElementsByClassName(content)[0];
const MAX_HEIGHT = CONTENT.scrollHeight;
const DURATION = MAX_HEIGHT * speed;
CONTENT.style.transitionDuration = `${DURATION}ms`;
CONTENT.style.transitionTimingFunction = cssEase;
BTN.addEventListener('click', () => {
CONTENT.style.height = isShow ? 0 : `${MAX_HEIGHT}px`;
isShow = !isShow;
});
}
};
// 実行
accordion({
// 初期値の上書き
speed: 1, // 1で100px 100msのスピード
cssEase: 'ease'
});
// 上書きなしで実行
// accordion();
<div class="js-ac">
<button class="js-ac_btn" type="button">ボタン</button>
<div class="js-ac_content">
<!-- コンテンツ -->
</div>
</div>
.js-ac {
overflow: hidden;
}
.js-ac_content {
height: 0;
transition-property: height;
}
引数で初期値を上書きすることにより、CSSクラス名やイージング、スピードを調整できます。
では、それぞれの役割をみていきましょう。
解説
引数
// 初期値
{
target = 'js-ac',
btn = 'js-ac_btn',
content = 'js-ac_content',
speed = 1.5,
cssEase = 'ease-out'
} = {}
仮引数部分は、オブジェクトの分割代入を利用して初期値を設定しています。実行時、実引数にオブジェクト形式で記述することにより、初期値を上書きすることができます。
詳しい解説は、こちらをどうぞ。
【JavaScript】関数の引数をオブジェクト形式にして、さらに初期値を設定する。
アコーディオン
// .js-acを取得
const TARGET = document.getElementsByClassName(target);
// .js-acの数だけループ処理
const TARGET_LENGTH = TARGET.length;
for (let i = 0; i < TARGET_LENGTH; i++) {
let isShow = false; // アコーディオンの開閉フラグ
const CURRENT_TARGET = TARGET[i]; // 対象の.js-acクラス
const BTN = CURRENT_TARGET.getElementsByClassName(btn)[0]; // 対象の.js-acクラス内のボタン要素
const CONTENT = CURRENT_TARGET.getElementsByClassName(content)[0]; // 対象の.js-acクラス内の開閉する要素
const MAX_HEIGHT = CONTENT.scrollHeight; // 対象の.js-acクラス内の開閉する要素の高さ
const DURATION = MAX_HEIGHT * speed; // 開閉スピード
CONTENT.style.transitionDuration = `${DURATION}ms`; // transition-durationを設定
CONTENT.style.transitionTimingFunction = cssEase; // transition-timing-functionを設定
// ボタンがクリックされるたびに、開閉する要素の高さと開閉フラグをトグル
BTN.addEventListener('click', () => {
CONTENT.style.height = isShow ? 0 : `${MAX_HEIGHT}px`;
isShow = !isShow;
});
}
scrollHeight()
メソットを使うと、要素のもともとの高さを取得できるので、CSSで対象の要素を予めheight: 0;
にしておけば、CSS Transitionで開閉をスムーズにアニメーションさせることができます。
また、const DURATION = MAX_HEIGHT * speed;
とすることにより、開閉する要素の高さが違っても、同じようなスピード感で開閉できるようにしています。
実行
// 実行
accordion({
// 初期値の上書き
speed: 1, // 1で100px 100msのスピード
cssEase: 'ease'
});
// 上書きなしで実行
// accordion();
実引数で、初期値を上書きすることができます。オブジェクト形式で書くので、見やすいです。
コードペン
See the Pen No jQuery Accordion by Otsuka Yuhi (@boltkeep) on CodePen.
以上!