ui.offcanvas.js 5.0 KB
Newer Older
L
LUO Minhui 已提交
1
define(function(require, exports, module) {
M
Minwe 已提交
2 3 4 5 6 7
  'use strict';

  require('zepto.outerdemension');
  require('zepto.extend.data');
  require('core');

M
Minwe 已提交
8 9 10 11 12
  var $ = window.Zepto;
  var UI = $.AMUI;
  var $win = $(window);
  var $doc = $(document);
  var scrollPos;
M
Minwe 已提交
13 14 15 16 17 18 19 20 21

  /**
   * @via https://github.com/uikit/uikit/blob/master/src/js/offcanvas.js
   * @license https://github.com/uikit/uikit/blob/master/LICENSE.md
   */

  var OffCanvas = function(element, options) {
    this.$element = $(element);
    this.options = options;
22
    this.active = null;
M
Minwe 已提交
23 24 25 26 27 28 29 30 31 32 33 34 35 36
    this.events();
  };

  OffCanvas.DEFAULTS = {
    duration: 300,
    effect: 'overlay' // {push|overlay}, push is too expensive
  };

  OffCanvas.prototype.open = function(relatedElement) {
    var $element = this.$element;

    if (!$element.length || $element.hasClass('am-active')) {
      return;
    }
L
LUO Minhui 已提交
37

38 39 40 41 42
    var effect = this.options.effect;
    var $html = $('html');
    var $body = $('body');
    var $bar = $element.find('.am-offcanvas-bar').first();
    var dir = $bar.hasClass('am-offcanvas-bar-flip') ? -1 : 1;
L
LUO Minhui 已提交
43

M
Minwe 已提交
44
    $bar.addClass('am-offcanvas-bar-' + effect);
L
LUO Minhui 已提交
45

M
Minwe 已提交
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
    scrollPos = {x: window.scrollX, y: window.scrollY};

    $element.addClass('am-active');

    $body.
        css({width: window.innerWidth, height: $win.height()}).
        addClass('am-offcanvas-page');

    if (effect !== 'overlay') {
      $body.css({
        'margin-left': $bar.outerWidth() * dir
      }).width(); // force redraw
    }

    $html.css('margin-top', scrollPos.y * -1);

    setTimeout(function() {
      $bar.addClass('am-offcanvas-bar-active').width();
    }, 0);

    $doc.trigger('open:offcanvas:amui');

68 69
    this.active = 1;

M
Minwe 已提交
70 71 72 73 74 75 76
    $element.off('.offcanvas.amui').
        on('click.offcanvas.amui swipe.offcanvas.amui', $.proxy(function(e) {
          var $target = $(e.target);

          if (!e.type.match(/swipe/)) {
            if ($target.hasClass('am-offcanvas-bar')) {
              return;
L
LUO Minhui 已提交
77 78
            }

M
Minwe 已提交
79 80
            if ($target.parents('.am-offcanvas-bar').first().length) {
              return;
L
LUO Minhui 已提交
81
            }
M
Minwe 已提交
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
          }

          // https://developer.mozilla.org/zh-CN/docs/DOM/event.stopImmediatePropagation
          e.stopImmediatePropagation();

          this.close();
        }, this));

    $html.on('keydown.offcanvas.amui', $.proxy(function(e) {
      if (e.keyCode === 27) { // ESC
        this.close();
      }
    }, this));
  };

  OffCanvas.prototype.close = function(relatedElement) {
98
    var me = this;
M
Minwe 已提交
99 100 101 102
    var $html = $('html');
    var $body = $('body');
    var $element = this.$element;
    var $bar = $element.find('.am-offcanvas-bar').first();
M
Minwe 已提交
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117

    if (!$element.length || !$element.hasClass('am-active')) {
      return;
    }

    $doc.trigger('close:offcanvas:amui');

    function complete() {
      $body.removeClass('am-offcanvas-page').
          css({width: '', height: '', 'margin-left': '', 'margin-right': ''});
      $element.removeClass('am-active');
      $bar.removeClass('am-offcanvas-bar-active');
      $html.css('margin-top', '');
      window.scrollTo(scrollPos.x, scrollPos.y);
      $doc.trigger('closed:offcanvas:amui');
118
      me.active = 0;
M
Minwe 已提交
119 120 121 122 123 124 125 126 127 128 129 130
    }

    if (UI.support.transition) {
      setTimeout(function() {
        $bar.removeClass('am-offcanvas-bar-active');
      }, 0);

      $body.css('margin-left', '').one(UI.support.transition.end, function() {
        complete();
      }).emulateTransitionEnd(this.options.duration);
    } else {
      complete();
L
LUO Minhui 已提交
131 132
    }

M
Minwe 已提交
133 134 135
    $element.off('.offcanvas.amui');
    $html.off('.offcanvas.amui');
  };
L
LUO Minhui 已提交
136

M
Minwe 已提交
137 138 139 140 141 142 143
  OffCanvas.prototype.events = function() {
    $doc.on('click.offcanvas.amui', '[data-am-dismiss="offcanvas"]',
        $.proxy(function(e) {
          e.preventDefault();
          this.close();
        }, this));

144 145 146 147 148
    $win.on('resize.offcanvas.amui orientationchange.offcanvas.amui',
        $.proxy(function(e) {
          this.active && this.close();
        }, this));

M
Minwe 已提交
149 150 151 152 153
    return this;
  };

  function Plugin(option, relatedElement) {
    return this.each(function() {
M
Minwe 已提交
154 155 156
      var $this = $(this);
      var data = $this.data('am.offcanvas');
      var options = $.extend({}, OffCanvas.DEFAULTS,
M
Minwe 已提交
157 158 159 160 161 162
                  typeof option == 'object' && option);

      if (!data) {
        $this.data('am.offcanvas', (data = new OffCanvas(this, options)));
        data.open(relatedElement);
      }
L
LUO Minhui 已提交
163

M
Minwe 已提交
164 165 166
      if (typeof option == 'string') {
        data[option] && data[option](relatedElement);
      }
L
LUO Minhui 已提交
167
    });
M
Minwe 已提交
168 169 170 171 172 173 174
  }

  $.fn.offCanvas = Plugin;

  // Init code
  $doc.on('click.offcanvas.amui', '[data-am-offcanvas]', function(e) {
    e.preventDefault();
M
Minwe 已提交
175 176 177 178 179
    var $this = $(this);
    var options = UI.utils.parseOptions($this.data('amOffcanvas'));
    var $target = $(options.target ||
            (this.href && this.href.replace(/.*(?=#[^\s]+$)/, '')));
    var option = $target.data('am.offcanvas') ? 'open' : options;
M
Minwe 已提交
180 181 182 183 184

    Plugin.call($target, option, this);
  });

  UI.offcanvas = OffCanvas;
L
LUO Minhui 已提交
185

M
Minwe 已提交
186
  module.exports = OffCanvas;
L
LUO Minhui 已提交
187 188 189
});

// TODO: 优化动画效果
M
Minwe 已提交
190
// http://dbushell.github.io/Responsive-Off-Canvas-Menu/step4.html