「脱jQuery」 生JSで.fadeIn()のように要素をフェードインで表示する

jQueryなしのネイティブJavaScriptで 要素をフェードイン する方法です。ここではフェードインする仕組みのみを実装していきます。

jQuery


$('.selector').fadeIn();

生JS


function fadeIn(node, duration) {
  // display: noneでないときは何もしない
  if (getComputedStyle(node).display !== 'none') return;
  
  // style属性にdisplay: noneが設定されていたとき
  if (node.style.display === 'none') {
    node.style.display = '';
  } else {
    node.style.display = 'block';
  }
  node.style.opacity = 0;

  var start = performance.now();
  
  requestAnimationFrame(function tick(timestamp) {
    // イージング計算式(linear)
    var easing = (timestamp - start) / duration;

    // opacityが1を超えないように
    node.style.opacity = Math.min(easing, 1);

    // opacityが1より小さいとき
    if (easing < 1) {
      requestAnimationFrame(tick);
    } else {
      node.style.opacity = '';
    }
  });
}

実際にはjQueryの .fadeIn() は色んなオプションがありますが、ここでは duration のみとしています。また、イージング関数も linear にしています。 easing の部分を変更すれば ease-in-out など作ることができますが、それはまた別の記事にまとめます。


fadeIn(document.querySelector('.selector'), 300);

こんな感じで使うことができます。

displayをblock以外でフェードインしたいとき


<div class="selector"></div>

.selector {
  display: none;
}

fadeIn(document.querySelector('.selector'), 300);

例えばこのようにしていると、フェードイン後は強制的に display: block になってしまいます。フェードイン後に例えば display: flex としたい場合は次のようにします。


<div class="selector" style="display: none"></div>

.selector {
  display: flex;
}

fadeIn(document.querySelector('.selector'), 300);

あらかじめ style 属性で非表示にしておけば大丈夫です。それか fadeIn 関数に引数でフェードイン後の display を指定できるようにするのもいいかもしれません。