はじめに
この記事ではjQueryのメソッドの一つである fadeIn()
と fadeOut()
をVanillaJS(素のJS)で実現するソリューションを紹介します。
背景
- 筆者はここ数年jQueryからVanillaJSへの移行をおこなっている。
- 筆者はjQueryのメソッドである
fadeIn()
とfadeOut()
を多用している。
課題
- jQueryの
fadeIn()
とfadeOut()
に該当するメソッドがVanillaJSには存在しない。 - 移行にあたり使いまわせるコードを残しておきたい。
仕様
できるだけ jQueryの fadeIn()
& fadeOut()
に近い仕様で実装したいと考えた。
- フェードイン/アウトをさせるDOM要素を指定する。
- フェードイン/アウトの時間をミリ秒で指定する。
- 非同期処理を実現する。
- 例えば、フェードイン/アウトのアニメーションの終了を待ってから次の処理を行うことができる。
- jQueryではコールバック関数を用いていたが、ここでは非同期処理(Promise or async & awaitを採用した。)
fadeIn()
fadeIn(element, duration?, display?);
引数 | 型 | 説明 |
---|---|---|
element |
HTMLElement |
フェードインしたいDOM要素を指定 |
duration |
number |
アニメーション時間をミリ秒で指定 |
display |
String |
表示時のdisplay プロパティを指定1
|
fadeOut()
fadeOut(element, duration?);
引数 | 型 | 説明 |
---|---|---|
element |
HTMLElement |
フェードアウトしたいDOM要素を指定 |
duration |
number |
アニメーション時間をミリ秒で指定 |
コード
const delay = 40; // fps=25
function fadeIn() {
return new Promise(async (resolve, reject) => {
if (arguments.length > 0) {
const elem = arguments[0];
if (elem.style.display === 'none' || elem.style.display === '') {
const duration = arguments.length === 2 ? arguments[1] : 500;
const display = arguments.length === 3 ? arguments[2] : 'block';
elem.style.display = display;
const coef = 1 / (duration / delay);
elem.style.opacity = 0;
var opacity = Number(elem.style.opacity);
var animation = setInterval(() => {
opacity += coef;
elem.style.opacity = opacity;
if (opacity >= 1) {
clearInterval(animation);
resolve(true);
}
}, delay);
}
}
});
}
function fadeOut() {
return new Promise(async (resolve, reject) => {
if (arguments.length > 0) {
const elem = arguments[0];
if (elem.style.display !== 'none') {
const duration = arguments.length === 2 ? arguments[1] : 500;
const coef = 1 / (duration / delay);
elem.style.opacity = 1.0;
var opacity = Number(elem.style.opacity);
var animation = setInterval(() => {
opacity -= coef;
elem.style.opacity = opacity;
if (opacity <= 0) {
elem.style.display = 'none';
clearInterval(animation);
resolve(true);
}
}, delay);
}
}
});
}
非同期処理として実装する
return new Promise(async (resolve, reject) => {
/* ここに処理を書く */
});
引数のチェック
// 引数は必ず一つ以上
if (arguments.length > 0) {
// 第1引数はDOM要素
const elem = arguments[0];
// 第2引数はデュレーション時間
const duration = arguments.length === 2 ? arguments[1] : 500;
// 第3引数はdisplayプロパティ (フェードインのみ)
const display = arguments.length === 3 ? arguments[2] : 'block';
}
フェード処理
フェードイン
// 現在表示されていないことを確認
if (elem.style.display === 'none' || elem.style.display === '') {
// 表示モードにしたうえで、不透明度を0にする。
elem.style.display = display;
elem.style.opacity = 0;
// 不透明度
// elem.style.opacityはString型なので、数値として扱うためにnumber型にキャストする必要がある。
// 初期値は0
var opacity = Number(elem.style.opacity);
// setIntervalが実行されるたびに不透明度に加算する定数
const coef = 1 / (duration / delay);
// setIntervalによって徐々に不透明度を1に近づける。
var animation = setInterval(() => {
opacity += coef;
elem.style.opacity = opacity;
// 終了条件 : 不透明度が1以上
if (opacity >= 1) {
clearInterval(animation);
resolve(true);
}
}, delay);
}
フェードアウト
// 現在表示されていることを確認
if (elem.style.display !== 'none') {
// 不透明度を1にする
elem.style.opacity = 1.0;
var opacity = Number(elem.style.opacity);
// setIntervalが実行されるたびに不透明度に減算する定数
const coef = 1 / (duration / delay);
// setIntervalによって徐々に不透明度を0に近づける。
var animation = setInterval(() => {
opacity -= coef;
elem.style.opacity = opacity;
// 終了条件 : 不透明度が0以下
if (opacity <= 0) {
elem.style.display = 'none';
clearInterval(animation);
resolve(true);
}
}, delay);
}
使い方
const elem = document.querySelector("#elem");
const duration = 600;
fadeIn(elem, duration, 'block');
fadeOut(elem, duration);
console.log("done");
非同期処理 (promise)
const elem = document.querySelector("#elem");
const duration = 600;
fadeIn(elem, duration, 'block')
.then(() => {
fadeOut(elem, duration)
.then(() => {
console.log("done");
});
});
非同期処理 (async/await)
const elem = document.querySelector("#elem");
const duration = 600;
await fadeIn(elem, duration, 'block');
await fadeOut(elem, duration);
console.log("done");
ライブラリ化
以上の処理をライブラリ化しました。(TypeScript対応済み)
インストール
-
JavaScript : ここから
fadeIOnu.js
をダウンロード -
TypeScript
npm i https://github.com/tomoya-onuki/fadeIOnu.js/
-
CSSのプロパティである
display
については公式のドキュメントを参考しにしてください。https://developer.mozilla.org/ja/docs/Web/CSS/display ↩