takahashiakira
7/6/2015 - 6:58 AM

Modal Class v2.0.0

Modal Class v2.0.0

#Modal Class

opne/close機能のみを持ったModalのベースとなるClass。
DOMの表示・非表示で管理する簡易的なModal。

※注意点
IE8以下はfilter (-ms-filter)を使うとclickイベントが設定できないバグがある。そのためfilterを使って背景を透明にすると閉じるボタンを設定できない。

Class (Prototype)

/**
 * Modal Class Description v2.0.0
 * @fileoverview opne/close機能のみを持ったModalのベースとなるClass。View管理していない場合はこちらを使う。
 *    対応ブラウザはPCのモダンブラウザ(IE8以上)
 *    jQuery依存
*/
var Modal = (function () {
  var constructor = function () {
    this.$el = {};
    this.$inner = {};
    this.$closeTrigger = {};
    this.$openTrigger = {};
    this.fadeSpeed = 0;
  };
  var proto = constructor.prototype;
  proto.set = function (args) {
    this.$el = $(args.el);
    this.$inner = this.$el.find('.js-modal-inner');
    this.$closeTrigger = this.$el.find('.js-modal-closeTrigger');
    this.$openTrigger = args.$openTrigger;
    this.fadeSpeed = args.fadeSpeed || 0;
    this.setEvents();
    return this;
  };
  proto.setEvents = function () {
    var that = this;
    this.$inner.on('click', function (e) {
      //* $elイベントのバブリングを停止 */
      e.stopPropagation();
    });
    this.$el.on('click', function (e) {
      //* 背景を押したら閉じるイベントハンドラ */
      e.preventDefault();
      that.close();
      return this;
    });
    this.$closeTrigger.on('click', function (e) {
      e.preventDefault();
      that.close();
      return this;
    });
    this.$openTrigger.on('click', function (e) {
      e.preventDefault();
      that.open(e);
      return this;
    });
    return this;
  };
  proto.open = function () {
    var that = this;
    this.$el.hide().removeClass('hide').fadeIn(this.fadeSpeed);
    $('html').css('overflowY', 'hidden');
    $('body').css('overflowY', 'scroll');
    this.$inner.css({
      'marginTop': -that.$inner.height()/2,
      'marginLeft': -that.$inner.width()/2
    });
    return this;
  };
  proto.close = function () {
    var that = this;
    this.$el.fadeOut(this.fadeSpeed, function(){
      that.$el.hide();
      $('html').css('overflowY', 'scroll');
      $('body').css('overflowY', 'hidden');
    });
    return this;
  };
  return constructor;
})();

Usage

HTML

<div class="js-modal-openTrigger1">open modal1</div>
<div class="js-modal-openTrigger2">open modal2</div>

<div id="js-modal1" class="js-modal">
  <div class="js-modal-inner">
    <div class="js-modal-closeTrigger">close</div>
    <p>modal1</p>
  </div>
</div>

<div id="js-modal2" class="js-modal">
  <div class="js-modal-inner">
    <div class="js-modal-closeTrigger">close</div>
    <p>modal2</p>
  </div>
</div>

CSS

/*
 * modal
 */

.js-modal {
  display: none;
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.8);
}
.js-modal-wrapper {
  position: relative;
  width: 100%;
  height: 100%;
}
.js-modal-inner {
  position: absolute;
  top: 50%;
  left: 50%;
  padding: 20px;
  background-color: #fff;
  border-radius: 4px;
}

JS

継承方法

var LocalModal = (function () {
  // 独自のコンストラクタを追加
  var constructor = function () {
    this.xxx;
  };
  var proto = constructor.prototype = new utils.Modal();
  // 既存メソッドの拡張方法
  proto.open = function (e) {
    // ...
    utils.Modal.prototype.open.apply(this);
    return this;
  };
  // 独自メソッドを追加
  proto.localMethod = function () {
    // ...
    return this;
  };
  return constructor;
})();

インスタンス化

var modal1 = new Modal();
var modal2 = new Modal();

modal1.set({
  el: '#js-modal1',
  $openTrigger: $('.js-modal-openTrigger1')
});
modal2.set({
  el: '#js-modal2',
  $openTrigger: $('.js-modal-openTrigger2'),
  fadeSpeed: 300
});