読者です 読者をやめる 読者になる 読者になる

frontendmemo

このサイトは、「html、css、js、ツールなどについて、自分が覚えたこと、またはいつも忘れて調べることを書き溜め、それが結果といて勉強したての初心者の方や自分と同じような技術レベルの人の助けになることを目的とするWebログ」、略してブログです。挨拶→http://frontendmemo.hatenablog.com/entry/2016/06/25/115845

【JavaScript】モジュールパターンを学ぶ~スムーススクロール機能を実装~

スポンサードリンク

モジュールパターンというものを最近知りました。プラグインでよく使われてる手法なのかなと思います。

モジュールパターンの参考記事

なぜモジュールパターンを使うか

上の記事によると利点は以下だそうです。

  • 他の処理との競合を防ぐ
  • 追加・置き換え・削除ができる
  • 機能別にコードを分割できる

といってもコードを書いてみないとわかりません。
上記記事を参考にしながら、スムーススクロールをモジュールパターンに置き換えてみました。

通常のスクリプト

  'use strict';
  var $win = $(window);
  /**
  * スムーススクロール
  */
  $.fn.smoothScroll = function(options){
    if(!this.length || this.attr('href') === '#'){
      return;
    }
    var o = $.extend({
      speed : 300, // スクロールの速度
      easing : 'swing' // スクロールの速度
    }, options);
    var self = this,
      speed  = o.speed,
      easing = o.easing,
      target, position, targetHref,
      hash = window.location.hash,
      // ブラウザを判定し対応している要素を変数にsetする
      $targetBody = $('html').scrollTop() > 0? $('html'): $('body');
    // 読み込み時にURLに#がある場合

    if(hash){
      $win.on('load', function(){
        self.trigger('click');
      });
    }
    this.on('click', function(){
      var $self = $(this);
      scroll($self);
    });
    // スクロールさせる関数
    function scroll($self){
      setPosition($self);
      $targetBody.not(':animated').animate({
        scrollTop : position
      }, speed, easing);
    }
    // 移動先の数値を取得するための関数
    function setPosition($self){
      // hrefの値を取得
      targetHref = $self.attr('href');
      // 移動先をアンカーを取得
      target = $(targetHref === '#top' ? $targetBody : targetHref);
      // 移動先の数値を取得
      position = target.offset().top;
    }
  };
  $('a[href^="#"]').smoothScroll();
})(window.jQuery);

モジュールパターンを使用したスクリプト

window.jQuery && (function ($) {
  'use strict';
  var $win = $(window);
  /**
  * スムーススクロール
  */
  var smoothScroll = smoothScroll || {
    util: {
      obj: {}
    }
  };
  smoothScroll.util.obj = (function(){
    var self = $('a[href^="#"]'),
      speed  = 300,
      easing = 'swing',
      target, position, targetHref,
      hash = window.location.hash,
      // ブラウザを判定し対応している要素を変数にsetする
      $targetBody = $('html').scrollTop() > 0? $('html'): $('body');

     var click = function(target){
      target.on('click', function(){
        var $self = $(this);
        smoothScroll.util.obj.scroll($self);
      });
    },
    scroll = function($self){
    // スクロールさせる関数a
      smoothScroll.util.obj.setPosition($self);
      $targetBody.not(':animated').animate({
        scrollTop : position
      }, speed, easing);
    },
    // 移動先の数値を取得するための関数a
    setPosition = function($self){
      // hrefの値を取得
      targetHref = $self.attr('href');
      // 移動先をアンカーを取得
      target = $(targetHref === '#top' ? $targetBody : targetHref);
      // 移動先の数値を取得
      position = target.offset().top;
    },
    init = function(){
      if(hash){
        $win.on('load', function(){
          $('a[href="' + hash + '"]').trigger('click');
        });
      }
    }
    init();
    return {
      click: click,
      scroll: scroll,
      setPosition: setPosition
    };
  })();
  smoothScroll.util.obj.click($('a[href^="#"]'));
})(window.jQuery);

DEMO

See the Pen oBxQbP by funclur (@funclur) on CodePen.


まとめ

以上、スムーススクロール機能をモジュールパターンに置き換えてみました。
詳しい説明は、自分が未だよくわかっていないので上記記事をご覧ください。
また、通常のスクリプトもグローバル環境汚染してるわけじゃないし、機能も追加できるし、はっきりとした利点が良くわかっていません。
ただかっこいいからモジュールパターン使っていこうかなという感じ笑

分かってきたらまた、ブログを更新するとします。