!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.Slideout=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ 'use strict'; /** * Module dependencies */ var decouple = require('decouple'); var Emitter = require('emitter'); /** * Privates */ var scrollTimeout; var scrolling = false; var doc = window.document; var html = doc.documentElement; var msPointerSupported = window.navigator.msPointerEnabled; var touch = { 'start': msPointerSupported ? 'MSPointerDown' : 'touchstart', 'move': msPointerSupported ? 'MSPointerMove' : 'touchmove', 'end': msPointerSupported ? 'MSPointerUp' : 'touchend' }; var prefix = (function prefix() { var regex = /^(Webkit|Khtml|Moz|ms|O)(?=[A-Z])/; var styleDeclaration = doc.getElementsByTagName('script')[0].style; for (var prop in styleDeclaration) { if (regex.test(prop)) { return '-' + prop.match(regex)[0].toLowerCase() + '-'; } } // Nothing found so far? Webkit does not enumerate over the CSS properties of the style object. // However (prop in style) returns the correct value, so we'll have to test for // the precence of a specific property if ('WebkitOpacity' in styleDeclaration) { return '-webkit-'; } if ('KhtmlOpacity' in styleDeclaration) { return '-khtml-'; } return ''; }()); function extend(destination, from) { for (var prop in from) { if (from[prop]) { destination[prop] = from[prop]; } } return destination; } function inherits(child, uber) { child.prototype = extend(child.prototype || {}, uber.prototype); } /** * Slideout constructor */ function Slideout(options) { options = options || {}; // Sets default values this._startOffsetX = 0; this._currentOffsetX = 0; this._opening = false; this._moved = false; this._opened = false; this._preventOpen = false; this._touch = options.touch === undefined ? true : options.touch && true; // Sets panel this.panel = options.panel; this.menu = options.menu; // Sets classnames if(this.panel.className.search('slideout-panel') === -1) { this.panel.className += ' slideout-panel'; } if(this.menu.className.search('slideout-menu') === -1) { this.menu.className += ' slideout-menu'; } // Sets options this._fx = options.fx || 'ease'; this._duration = parseInt(options.duration, 10) || 300; this._tolerance = parseInt(options.tolerance, 10) || 70; this._padding = this._translateTo = parseInt(options.padding, 10) || 256; this._orientation = options.side === 'right' ? -1 : 1; this._translateTo *= this._orientation; // Init touch events if (this._touch) { this._initTouchEvents(); } } /** * Inherits from Emitter */ inherits(Slideout, Emitter); /** * Opens the slideout menu. */ Slideout.prototype.open = function() { var self = this; this.emit('beforeopen'); if (html.className.search('slideout-open') === -1) { html.className += ' slideout-open'; } this._setTransition(); this._translateXTo(this._translateTo); this._opened = true; setTimeout(function() { self.panel.style.transition = self.panel.style['-webkit-transition'] = ''; self.emit('open'); }, this._duration + 50); return this; }; /** * Closes slideout menu. */ Slideout.prototype.close = function() { var self = this; if (!this.isOpen() && !this._opening) { return this; } this.emit('beforeclose'); this._setTransition(); this._translateXTo(0); this._opened = false; setTimeout(function() { html.className = html.className.replace(/ slideout-open/, ''); self.panel.style.transition = self.panel.style['-webkit-transition'] = self.panel.style[prefix + 'transform'] = self.panel.style.transform = ''; self.emit('close'); }, this._duration + 50); return this; }; /** * Toggles (open/close) slideout menu. */ Slideout.prototype.toggle = function() { return this.isOpen() ? this.close() : this.open(); }; /** * Returns true if the slideout is currently open, and false if it is closed. */ Slideout.prototype.isOpen = function() { return this._opened; }; /** * Translates panel and updates currentOffset with a given X point */ Slideout.prototype._translateXTo = function(translateX) { this._currentOffsetX = translateX; this.panel.style[prefix + 'transform'] = this.panel.style.transform = 'translate3d(' + translateX + 'px, 0, 0)'; }; /** * Set transition properties */ Slideout.prototype._setTransition = function() { this.panel.style[prefix + 'transition'] = this.panel.style.transition = prefix + 'transform ' + this._duration + 'ms ' + this._fx; }; /** * Initializes touch event */ Slideout.prototype._initTouchEvents = function() { var self = this; /** * Decouple scroll event */ this._onScrollFn = decouple(doc, 'scroll', function() { if (!self._moved) { clearTimeout(scrollTimeout); scrolling = true; scrollTimeout = setTimeout(function() { scrolling = false; }, 250); } }); /** * Prevents touchmove event if slideout is moving */ this._preventMove = function(eve) { if (self._moved) { eve.preventDefault(); } }; doc.addEventListener(touch.move, this._preventMove); /** * Resets values on touchstart */ this._resetTouchFn = function(eve) { if (typeof eve.touches === 'undefined') { return; } self._moved = false; self._opening = false; self._startOffsetX = eve.touches[0].pageX; self._preventOpen = (!self._touch || (!self.isOpen() && self.menu.clientWidth !== 0)); }; this.panel.addEventListener(touch.start, this._resetTouchFn); /** * Resets values on touchcancel */ this._onTouchCancelFn = function() { self._moved = false; self._opening = false; }; this.panel.addEventListener('touchcancel', this._onTouchCancelFn); /** * Toggles slideout on touchend */ this._onTouchEndFn = function() { if (self._moved) { (self._opening && Math.abs(self._currentOffsetX) > self._tolerance) ? self.open() : self.close(); } self._moved = false; }; this.panel.addEventListener(touch.end, this._onTouchEndFn); /** * Translates panel on touchmove */ this._onTouchMoveFn = function(eve) { self.emit('touchmove', eve.target); if (scrolling || self._preventOpen || typeof eve.touches === 'undefined') { return; } var dif_x = eve.touches[0].clientX - self._startOffsetX; var translateX = self._currentOffsetX = dif_x; if (Math.abs(translateX) > self._padding) { return; } if (Math.abs(dif_x) > 20) { self._opening = true; var oriented_dif_x = dif_x * self._orientation; if (self._opened && oriented_dif_x > 0 || !self._opened && oriented_dif_x < 0) { return; } if (oriented_dif_x <= 0) { translateX = dif_x + self._padding * self._orientation; self._opening = false; } if (!self._moved && html.className.search('slideout-open') === -1) { html.className += ' slideout-open'; } self.panel.style[prefix + 'transform'] = self.panel.style.transform = 'translate3d(' + translateX + 'px, 0, 0)'; self.emit('translate', translateX, eve.target); self._moved = true; } }; this.panel.addEventListener(touch.move, this._onTouchMoveFn); }; Slideout.prototype.enableTouch = function() { this._touch = true; return this; }; Slideout.prototype.disableTouch = function() { this._touch = false; return this; }; Slideout.prototype.destroy = function() { // Close before clean this.close(); // Remove event listeners doc.removeEventListener(touch.move, this._preventMove); this.panel.removeEventListener(touch.start, this._resetTouchFn); this.panel.removeEventListener('touchcancel', this._onTouchCancelFn); this.panel.removeEventListener(touch.end, this._onTouchEndFn); this.panel.removeEventListener(touch.move, this._onTouchMoveFn); doc.removeEventListener('scroll', this._onScrollFn); // Remove methods this.open = this.close = function() {}; // Return the instance so it can be easily dereferenced return this; }; /** * Expose Slideout */ module.exports = Slideout; },{"decouple":2,"emitter":3}],2:[function(require,module,exports){ 'use strict'; var requestAnimFrame = (function() { return window.requestAnimationFrame || window.webkitRequestAnimationFrame || function (callback) { window.setTimeout(callback, 1000 / 60); }; }()); function decouple(node, event, fn) { var eve, tracking = false; function captureEvent(e) { eve = e; track(); } function track() { if (!tracking) { requestAnimFrame(update); tracking = true; } } function update() { fn.call(node, eve); tracking = false; } node.addEventListener(event, captureEvent, false); return captureEvent; } /** * Expose decouple */ module.exports = decouple; },{}],3:[function(require,module,exports){ "use strict"; var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; exports.__esModule = true; /** * Creates a new instance of Emitter. * @class * @returns {Object} Returns a new instance of Emitter. * @example * // Creates a new instance of Emitter. * var Emitter = require('emitter'); * * var emitter = new Emitter(); */ var Emitter = (function () { function Emitter() { _classCallCheck(this, Emitter); } /** * Adds a listener to the collection for the specified event. * @memberof! Emitter.prototype * @function * @param {String} event - The event name. * @param {Function} listener - A listener function to add. * @returns {Object} Returns an instance of Emitter. * @example * // Add an event listener to "foo" event. * emitter.on('foo', listener); */ Emitter.prototype.on = function on(event, listener) { // Use the current collection or create it. this._eventCollection = this._eventCollection || {}; // Use the current collection of an event or create it. this._eventCollection[event] = this._eventCollection[event] || []; // Appends the listener into the collection of the given event this._eventCollection[event].push(listener); return this; }; /** * Adds a listener to the collection for the specified event that will be called only once. * @memberof! Emitter.prototype * @function * @param {String} event - The event name. * @param {Function} listener - A listener function to add. * @returns {Object} Returns an instance of Emitter. * @example * // Will add an event handler to "foo" event once. * emitter.once('foo', listener); */ Emitter.prototype.once = function once(event, listener) { var self = this; function fn() { self.off(event, fn); listener.apply(this, arguments); } fn.listener = listener; this.on(event, fn); return this; }; /** * Removes a listener from the collection for the specified event. * @memberof! Emitter.prototype * @function * @param {String} event - The event name. * @param {Function} listener - A listener function to remove. * @returns {Object} Returns an instance of Emitter. * @example * // Remove a given listener. * emitter.off('foo', listener); */ Emitter.prototype.off = function off(event, listener) { var listeners = undefined; // Defines listeners value. if (!this._eventCollection || !(listeners = this._eventCollection[event])) { return this; } listeners.forEach(function (fn, i) { if (fn === listener || fn.listener === listener) { // Removes the given listener. listeners.splice(i, 1); } }); // Removes an empty event collection. if (listeners.length === 0) { delete this._eventCollection[event]; } return this; }; /** * Execute each item in the listener collection in order with the specified data. * @memberof! Emitter.prototype * @function * @param {String} event - The name of the event you want to emit. * @param {...Object} data - Data to pass to the listeners. * @returns {Object} Returns an instance of Emitter. * @example * // Emits the "foo" event with 'param1' and 'param2' as arguments. * emitter.emit('foo', 'param1', 'param2'); */ Emitter.prototype.emit = function emit(event) { var _this = this; for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { args[_key - 1] = arguments[_key]; } var listeners = undefined; // Defines listeners value. if (!this._eventCollection || !(listeners = this._eventCollection[event])) { return this; } // Clone listeners listeners = listeners.slice(0); listeners.forEach(function (fn) { return fn.apply(_this, args); }); return this; }; return Emitter; })(); /** * Exports Emitter */ exports["default"] = Emitter; module.exports = exports["default"]; },{}]},{},[1])(1) });