VanillaJSでslideDownを実装する

jQueryのslideDown()やslideUp()のような挙動を、VanillaJSで実装してみます。

サンプルコード

slideDown・slideUp・slideToggleの関数を用意します。

/**
 * 要素をスライドダウンで表示する
 * @param {object} element - 対象要素
 * @param {number} speed   - スライド速度(ms)
 */
function slideDown(element, speed = 400) {
	if(element.classList.contains('is-sliding')) return; // スライド中の場合は処理を行わない
	if(window.getComputedStyle(element).display !== 'none') return; // 要素が非表示でない場合は処理を行わない
	element.classList.add('is-sliding'); // スライド中判別用のclass追加

	// 要素を表示して高さを取得
	element.style.removeProperty('display');
	const display = window.getComputedStyle(element).display;
	if(display === 'none') {
		element.style.display = 'block';
	}
	const height = element.offsetHeight;

	// スライド実行前の設定
	element.style.overflow = 'hidden';
	// 各値にスライド開始時の値を設定
	element.style.height = 0;
	element.style.paddingTop = 0;
	element.style.paddingBottom = 0;
	element.style.marginTop = 0;
	element.style.marginBottom = 0;

	// スライド実行前の設定
	setTimeout(function() {
		// transitionの設定
		element.style.transitionProperty = 'height, margin-top, margin-bottom, padding-top, padding-bottom';
		element.style.transitionDuration = `${speed}ms`;
		// 各値をスライド終了時の値に変更
		element.style.height = `${height}px`;
		removeStyleProperties(element, [
			'margin-top', 'margin-bottom', 'padding-top', 'padding-bottom'
		]);
	}, 0);

	// スライド実行後の設定
	setTimeout(function() {
		// style属性内の不要なプロパティを削除
		removeStyleProperties(element, [
			'height', 'overflow', 'transition-property', 'transition-duration'
		]);
		element.classList.remove('is-sliding'); // スライド中判別用のclass削除
	}, speed);
}

/**
 * 要素をスライドアップで非表示にする
 * @param {object} element - 対象要素
 * @param {number} speed   - スライド速度(ms)
 */
function slideUp(element, speed = 400) {
	if(element.classList.contains('is-sliding')) return; // スライド中の場合は処理を行わない
	if(window.getComputedStyle(element).display === 'none') return; // 要素が非表示の場合は処理を行わない
	element.classList.add('is-sliding'); // スライド中判別用のclass追加

	// スライド実行前の設定
	element.style.overflow = 'hidden';
	// スライド開始時の値を設定
	element.style.height = `${element.offsetHeight}px`;

	// スライド実行前の設定
	setTimeout(function() {
		// transitionの設定
		element.style.transitionProperty = 'height, margin-top, margin-bottom, padding-top, padding-bottom';
		element.style.transitionDuration = `${speed}ms`;
		// 各値をスライド終了時の値に変更
		element.style.height = 0;
		element.style.paddingTop = 0;
		element.style.paddingBottom = 0;
		element.style.marginTop = 0;
		element.style.marginBottom = 0;
	}, 0);

	// スライド実行後の設定
	setTimeout(function() {
		// 要素を非表示に変更
		element.style.display = 'none';
		// style属性内の不要なプロパティを削除
		removeStyleProperties(element, [
			'height', 'overflow', 'transition-property', 'transition-duration',
			'margin-top', 'margin-bottom', 'padding-top', 'padding-bottom'
		]);
		element.classList.remove('is-sliding'); // スライド中判別用のclass削除
	}, speed);
}

/**
 * 要素の表示状態に応じてslideDown/slideUpの動作を行う
 * @param {object} element - 対象要素
 * @param {number} speed   - スライド速度(ms)
 */
function slideToggle(element, speed = 400) {
	// 要素が非表示の場合はslideDownを実行
	if(window.getComputedStyle(element).display === 'none') {
		slideDown(element, speed);
	// 要素が非表示でない場合はslideUpを実行
} else {
		slideUp(element, speed);
	}
}

/**
 * 要素のstyle属性から指定したプロパティを除去する
 * @param {object} element   - 対象要素
 * @param {array} properties - 除去するプロパティ
 */
function removeStyleProperties(element, properties) {
	for(const property of properties) {
		element.style.removeProperty(property);
	}
}

基本的にはコード内に記載しているコメントの通りです。
スライド時はoverflow: hidden を設定した上で、height(+margin・padding)の値を変更してアニメーションを行っています。
jQueryではstyle属性内のheightの値を直接変更してアニメーションを行っていますが、今回のサンプルではtransitionを使ってアニメーションを行うようにしています、

実際に動作を試してみます。

<button id="slideDown">slideDown</button>
<button id="slideUp">slideUp</button>
<button id="slideToggle">slideToggle</button>
<div id="sample">
  テストテストテスト<br>
  テストテストテスト<br>
  テストテストテスト
</div>

各ボタンクリック時に関数を実行するように設定します。

const elem = document.getElementById('sample');
document.getElementById('slideDown').addEventListener('click', function() {
	slideDown(elem, 1000);
});
document.getElementById('slideUp').addEventListener('click', function() {
	slideUp(elem, 1000);
});
document.getElementById('slideToggle').addEventListener('click', function() {
	slideToggle(elem, 1000);
});

これでVanillaJSでスライド系の処理を実装できました。
slideDown・slideUp・slideToggleのデモページ

このエントリーをはてなブックマークに追加

関連記事

コメントを残す

メールアドレスが公開されることはありません。
* が付いている欄は必須項目です

CAPTCHA


コメントが承認されるまで時間がかかります。

2024年4月
 123456
78910111213
14151617181920
21222324252627
282930