プロセスを考えてJavaScriptを組む

Blog

エンジニアの山田です。
世の中、優秀なライブラリが溢れていて、どうやったらできるか考える前にどのライブラリを使えばできるかを考えてしまいます。
今回は原点回帰!!ライブラリに頼らず、しっかりとプロセスを考えて実装したいと思います。

試しにスクロールアニメーションを実装してみたいと思います。

イベントハンドラーを設定する

まずはイベントハンドラーを設定します。
手順としては、

  1. ユーザーがスクロールする。
  2. スクロールが一定の高さまで来たら、イベント発火。

コードにすると、

(function($) {

  var windowH = $(window).height();

  $(window).on('load scroll', function() {
    var scrollTop = $(window).scrollTop();
    var animationend = false;
    if( scrollTop + windowH > target.offset().top && !animationend ) {
      /* ここにアニメーションの内容を書く */
      animationend = true;
    }
  })

})(jQuery);

細かな説明は割愛させていただきますが、if分の条件を「スクロール量 + ウィンドウの高さが要素のトップの位置を上回ったら」とすることで、要素がウィンドウ内に見えるようになったらイベントが発火にするようになっています。

スクロール量だけだと、スクロールする度にアニメーションが起こってしまう(記述によってはただの誤作動が起こる)ため、一度アニメーションが起こったあとにフラグを付けておくことで無駄な発火を防止します。
今回はanimationendをbooleanで判定するようにしています。

発火位置を真ん中にしたい場合は、ウィンドウサイズの半分なので、
if( scrollTop + (windowH / 2) > target.offset().top && !animationend )
とすれば、ウィンドウの半分の位置で発火させることもできます。または、
if( scrollTop + windowH > target.offset().top + target.height() * .5 && !animationend )
とすることで、要素の半分がウィンドウに入って来たらという形にすることもできます。
このあたりはお好みによって変えてみてください。

ひとまずこれで最低限のイベントハンドラーは設定できることができました。

自作でプラグインを作って、関数をまとめる

続いては、これらを関数にまとめて複数の要素にも対応できるようにしたいと思います。

(function($) {

  var windowH = $(window).height();

  $.fn.myPlugin = function() {
    var target = this;
    $(window).on('load scroll', function() {
      var scrollTop = $(window).scrollTop();
      var animationend = false;
      if( scrollTop + windowH > target.offset().top && !animationend ) {
        /* ここにアニメーションの内容を書く */
        animationend = true;
      }
    })
  }

  $('.section').each(function(index, element) {
    $(element).myPlugin();
  })

})(jQuery);

他人には頼らず自作プラグインを作成!
$.fn.myPluginとして関数を作ることで、プラグイン化することができます。
myPluginの部分は任意で名前を設定することができますので、状況に応じて変更してください。
これをeachで回すことで.sectionがウィンドウ内に入って来る度にアニメーションを発火させることができます。
プラグインを作るって難しいように思えますが、ちょっとしたものを作るだけであればそんなに難しくありません。

これでは全て同じアニメーションしかできませんので、最後に個々にアニメーションを設定していきたいと思います。

個々にアニメーションを設定する

(function($) {

  var windowH = $(window).height();

  $.fn.myPlugin = function(callback) {
    var target = this;
    $(window).on('load scroll', function() {
      var scrollTop = $(window).scrollTop();
      var animationend = false;
      if( scrollTop + windowH > target.offset().top ) {
        callback(target);
      }
    })
  }

  function animation1(target) {
    /* ここにアニメーション1の内容を書く */
  }

  function animation2(target) {
    /* ここにアニメーション2の内容を書く */
  }

  function animation3(target) {
    /* ここにアニメーション3の内容を書く */
  }

  function animation4(target) {
    /* ここにアニメーション4の内容を書く */
  }

  function animation5(target) {
    /* ここにアニメーション5の内容を書く */
  }

  $('.section1').myPlugin(animation1);
  $('.section2').myPlugin(animation2);
  $('.section3').myPlugin(animation3);
  $('.section4').myPlugin(animation4);
  $('.section5').myPlugin(animation5);

})(jQuery);

少し長くなりましたが、これで個々にアニメーションを設定することができます。
個々のアニメーションをそれぞれの関数にまとめておくと使いやすくなると思います。
それを先ほど作った自作のプラグインにコールバック関数として引数を与えると簡単にスクロールアクションが作れます。

DEMO

DEMO

アニメーションに関しては、GreenSock社のライブラリがあまりに優秀なので頼りました。。。
優秀なライブラリは多くありますが、頼りすぎずプロセスを考えて実装することがステップアップに繋がると思います!
今後も工数と相談して自力で頑張りたいと思います。