|
|
/**
|
|
|
* off-canvas
|
|
|
* @param {type} $
|
|
|
* @param {type} window
|
|
|
* @param {type} document
|
|
|
* @param {type} action
|
|
|
* @returns {undefined}
|
|
|
*/
|
|
|
(function($, window, document, name) {
|
|
|
var CLASS_OFF_CANVAS_LEFT = $.className('off-canvas-left');
|
|
|
var CLASS_OFF_CANVAS_RIGHT = $.className('off-canvas-right');
|
|
|
var CLASS_ACTION_BACKDROP = $.className('off-canvas-backdrop');
|
|
|
var CLASS_OFF_CANVAS_WRAP = $.className('off-canvas-wrap');
|
|
|
|
|
|
var CLASS_SLIDE_IN = $.className('slide-in');
|
|
|
var CLASS_ACTIVE = $.className('active');
|
|
|
|
|
|
|
|
|
var CLASS_TRANSITIONING = $.className('transitioning');
|
|
|
|
|
|
var SELECTOR_INNER_WRAP = $.classSelector('.inner-wrap');
|
|
|
|
|
|
|
|
|
var OffCanvas = $.Class.extend({
|
|
|
init: function(element, options) {
|
|
|
this.wrapper = this.element = element;
|
|
|
this.scroller = this.wrapper.querySelector(SELECTOR_INNER_WRAP);
|
|
|
this.classList = this.wrapper.classList;
|
|
|
if (this.scroller) {
|
|
|
this.options = $.extend(true, {
|
|
|
dragThresholdX: 10,
|
|
|
scale: 0.8,
|
|
|
opacity: 0.1,
|
|
|
preventDefaultException: {
|
|
|
tagName: /^(INPUT|TEXTAREA|BUTTON|SELECT|VIDEO)$/
|
|
|
},
|
|
|
}, options);
|
|
|
document.body.classList.add($.className('fullscreen')); //fullscreen
|
|
|
this.refresh();
|
|
|
this.initEvent();
|
|
|
}
|
|
|
},
|
|
|
_preventDefaultException: function(el, exceptions) {
|
|
|
for (var i in exceptions) {
|
|
|
if (exceptions[i].test(el[i])) {
|
|
|
return true;
|
|
|
}
|
|
|
}
|
|
|
return false;
|
|
|
},
|
|
|
refresh: function(offCanvas) {
|
|
|
// offCanvas && !offCanvas.classList.contains(CLASS_ACTIVE) && this.classList.remove(CLASS_ACTIVE);
|
|
|
this.slideIn = this.classList.contains(CLASS_SLIDE_IN);
|
|
|
this.scalable = this.classList.contains($.className('scalable')) && !this.slideIn;
|
|
|
this.scroller = this.wrapper.querySelector(SELECTOR_INNER_WRAP);
|
|
|
// !offCanvas && this.scroller.classList.remove(CLASS_TRANSITIONING);
|
|
|
// !offCanvas && this.scroller.setAttribute('style', '');
|
|
|
this.offCanvasLefts = this.wrapper.querySelectorAll('.' + CLASS_OFF_CANVAS_LEFT);
|
|
|
this.offCanvasRights = this.wrapper.querySelectorAll('.' + CLASS_OFF_CANVAS_RIGHT);
|
|
|
if (offCanvas) {
|
|
|
if (offCanvas.classList.contains(CLASS_OFF_CANVAS_LEFT)) {
|
|
|
this.offCanvasLeft = offCanvas;
|
|
|
} else if (offCanvas.classList.contains(CLASS_OFF_CANVAS_RIGHT)) {
|
|
|
this.offCanvasRight = offCanvas;
|
|
|
}
|
|
|
} else {
|
|
|
this.offCanvasRight = this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_RIGHT);
|
|
|
this.offCanvasLeft = this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_LEFT);
|
|
|
}
|
|
|
this.offCanvasRightWidth = this.offCanvasLeftWidth = 0;
|
|
|
this.offCanvasLeftSlideIn = this.offCanvasRightSlideIn = false;
|
|
|
if (this.offCanvasRight) {
|
|
|
this.offCanvasRightWidth = this.offCanvasRight.offsetWidth;
|
|
|
this.offCanvasRightSlideIn = this.slideIn && (this.offCanvasRight.parentNode === this.wrapper);
|
|
|
// this.offCanvasRight.classList.remove(CLASS_TRANSITIONING);
|
|
|
// this.offCanvasRight.classList.remove(CLASS_ACTIVE);
|
|
|
// this.offCanvasRight.setAttribute('style', '');
|
|
|
}
|
|
|
if (this.offCanvasLeft) {
|
|
|
this.offCanvasLeftWidth = this.offCanvasLeft.offsetWidth;
|
|
|
this.offCanvasLeftSlideIn = this.slideIn && (this.offCanvasLeft.parentNode === this.wrapper);
|
|
|
// this.offCanvasLeft.classList.remove(CLASS_TRANSITIONING);
|
|
|
// this.offCanvasLeft.classList.remove(CLASS_ACTIVE);
|
|
|
// this.offCanvasLeft.setAttribute('style', '');
|
|
|
}
|
|
|
this.backdrop = this.scroller.querySelector('.' + CLASS_ACTION_BACKDROP);
|
|
|
|
|
|
this.options.dragThresholdX = this.options.dragThresholdX || 10;
|
|
|
|
|
|
this.visible = false;
|
|
|
this.startX = null;
|
|
|
this.lastX = null;
|
|
|
this.offsetX = null;
|
|
|
this.lastTranslateX = null;
|
|
|
},
|
|
|
handleEvent: function(e) {
|
|
|
switch (e.type) {
|
|
|
case $.EVENT_START:
|
|
|
e.target && !this._preventDefaultException(e.target, this.options.preventDefaultException) && e.preventDefault();
|
|
|
break;
|
|
|
case 'webkitTransitionEnd': //有个bug需要处理,需要考虑假设没有触发webkitTransitionEnd的情况
|
|
|
if (e.target === this.scroller) {
|
|
|
this._dispatchEvent();
|
|
|
}
|
|
|
break;
|
|
|
case 'drag':
|
|
|
var detail = e.detail;
|
|
|
if (!this.startX) {
|
|
|
this.startX = detail.center.x;
|
|
|
this.lastX = this.startX;
|
|
|
} else {
|
|
|
this.lastX = detail.center.x;
|
|
|
}
|
|
|
if (!this.isDragging && Math.abs(this.lastX - this.startX) > this.options.dragThresholdX && (detail.direction === 'left' || (detail.direction === 'right'))) {
|
|
|
if (this.slideIn) {
|
|
|
this.scroller = this.wrapper.querySelector(SELECTOR_INNER_WRAP);
|
|
|
if (this.classList.contains(CLASS_ACTIVE)) {
|
|
|
if (this.offCanvasRight && this.offCanvasRight.classList.contains(CLASS_ACTIVE)) {
|
|
|
this.offCanvas = this.offCanvasRight;
|
|
|
this.offCanvasWidth = this.offCanvasRightWidth;
|
|
|
} else {
|
|
|
this.offCanvas = this.offCanvasLeft;
|
|
|
this.offCanvasWidth = this.offCanvasLeftWidth;
|
|
|
}
|
|
|
} else {
|
|
|
if (detail.direction === 'left' && this.offCanvasRight) {
|
|
|
this.offCanvas = this.offCanvasRight;
|
|
|
this.offCanvasWidth = this.offCanvasRightWidth;
|
|
|
} else if (detail.direction === 'right' && this.offCanvasLeft) {
|
|
|
this.offCanvas = this.offCanvasLeft;
|
|
|
this.offCanvasWidth = this.offCanvasLeftWidth;
|
|
|
} else {
|
|
|
this.scroller = null;
|
|
|
}
|
|
|
}
|
|
|
} else {
|
|
|
if (this.classList.contains(CLASS_ACTIVE)) {
|
|
|
if (detail.direction === 'left') {
|
|
|
this.offCanvas = this.offCanvasLeft;
|
|
|
this.offCanvasWidth = this.offCanvasLeftWidth;
|
|
|
} else {
|
|
|
this.offCanvas = this.offCanvasRight;
|
|
|
this.offCanvasWidth = this.offCanvasRightWidth;
|
|
|
}
|
|
|
} else {
|
|
|
if (detail.direction === 'right') {
|
|
|
this.offCanvas = this.offCanvasLeft;
|
|
|
this.offCanvasWidth = this.offCanvasLeftWidth;
|
|
|
} else {
|
|
|
this.offCanvas = this.offCanvasRight;
|
|
|
this.offCanvasWidth = this.offCanvasRightWidth;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
if (this.offCanvas && this.scroller) {
|
|
|
this.startX = this.lastX;
|
|
|
this.isDragging = true;
|
|
|
|
|
|
$.gestures.session.lockDirection = true; //锁定方向
|
|
|
$.gestures.session.startDirection = detail.direction;
|
|
|
|
|
|
this.offCanvas.classList.remove(CLASS_TRANSITIONING);
|
|
|
this.scroller.classList.remove(CLASS_TRANSITIONING);
|
|
|
this.offsetX = this.getTranslateX();
|
|
|
this._initOffCanvasVisible();
|
|
|
}
|
|
|
}
|
|
|
if (this.isDragging) {
|
|
|
this.updateTranslate(this.offsetX + (this.lastX - this.startX));
|
|
|
detail.gesture.preventDefault();
|
|
|
e.stopPropagation();
|
|
|
}
|
|
|
break;
|
|
|
case 'dragend':
|
|
|
if (this.isDragging) {
|
|
|
var detail = e.detail;
|
|
|
var direction = detail.direction;
|
|
|
this.isDragging = false;
|
|
|
this.offCanvas.classList.add(CLASS_TRANSITIONING);
|
|
|
this.scroller.classList.add(CLASS_TRANSITIONING);
|
|
|
var ratio = 0;
|
|
|
var x = this.getTranslateX();
|
|
|
if (!this.slideIn) {
|
|
|
if (x >= 0) {
|
|
|
ratio = (this.offCanvasLeftWidth && (x / this.offCanvasLeftWidth)) || 0;
|
|
|
} else {
|
|
|
ratio = (this.offCanvasRightWidth && (x / this.offCanvasRightWidth)) || 0;
|
|
|
}
|
|
|
if (ratio === 0) {
|
|
|
this.openPercentage(0);
|
|
|
this._dispatchEvent(); //此处不触发webkitTransitionEnd,所以手动dispatch
|
|
|
return;
|
|
|
}
|
|
|
if (direction === 'right' && ratio >= 0 && (ratio >= 0.5 || detail.swipe)) { //右滑打开
|
|
|
this.openPercentage(100);
|
|
|
} else if (direction === 'right' && ratio < 0 && (ratio > -0.5 || detail.swipe)) { //右滑关闭
|
|
|
this.openPercentage(0);
|
|
|
} else if (direction === 'right' && ratio > 0 && ratio < 0.5) { //右滑还原关闭
|
|
|
this.openPercentage(0);
|
|
|
} else if (direction === 'right' && ratio < 0.5) { //右滑还原打开
|
|
|
this.openPercentage(-100);
|
|
|
} else if (direction === 'left' && ratio <= 0 && (ratio <= -0.5 || detail.swipe)) { //左滑打开
|
|
|
this.openPercentage(-100);
|
|
|
} else if (direction === 'left' && ratio > 0 && (ratio <= 0.5 || detail.swipe)) { //左滑关闭
|
|
|
this.openPercentage(0);
|
|
|
} else if (direction === 'left' && ratio < 0 && ratio >= -0.5) { //左滑还原关闭
|
|
|
this.openPercentage(0);
|
|
|
} else if (direction === 'left' && ratio > 0.5) { //左滑还原打开
|
|
|
this.openPercentage(100);
|
|
|
} else { //默认关闭
|
|
|
this.openPercentage(0);
|
|
|
}
|
|
|
if (ratio === 1 || ratio === -1) { //此处不触发webkitTransitionEnd,所以手动dispatch
|
|
|
this._dispatchEvent();
|
|
|
}
|
|
|
} else {
|
|
|
if (x >= 0) {
|
|
|
ratio = (this.offCanvasRightWidth && (x / this.offCanvasRightWidth)) || 0;
|
|
|
} else {
|
|
|
ratio = (this.offCanvasLeftWidth && (x / this.offCanvasLeftWidth)) || 0;
|
|
|
}
|
|
|
if (direction === 'right' && ratio <= 0 && (ratio >= -0.5 || detail.swipe)) { //右滑打开
|
|
|
this.openPercentage(100);
|
|
|
} else if (direction === 'right' && ratio > 0 && (ratio >= 0.5 || detail.swipe)) { //右滑关闭
|
|
|
this.openPercentage(0);
|
|
|
} else if (direction === 'right' && ratio <= -0.5) { //右滑还原关闭
|
|
|
this.openPercentage(0);
|
|
|
} else if (direction === 'right' && ratio > 0 && ratio <= 0.5) { //右滑还原打开
|
|
|
this.openPercentage(-100);
|
|
|
} else if (direction === 'left' && ratio >= 0 && (ratio <= 0.5 || detail.swipe)) { //左滑打开
|
|
|
this.openPercentage(-100);
|
|
|
} else if (direction === 'left' && ratio < 0 && (ratio <= -0.5 || detail.swipe)) { //左滑关闭
|
|
|
this.openPercentage(0);
|
|
|
} else if (direction === 'left' && ratio >= 0.5) { //左滑还原关闭
|
|
|
this.openPercentage(0);
|
|
|
} else if (direction === 'left' && ratio >= -0.5 && ratio < 0) { //左滑还原打开
|
|
|
this.openPercentage(100);
|
|
|
} else {
|
|
|
this.openPercentage(0);
|
|
|
}
|
|
|
if (ratio === 1 || ratio === -1 || ratio === 0) {
|
|
|
this._dispatchEvent();
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
}
|
|
|
}
|
|
|
break;
|
|
|
}
|
|
|
},
|
|
|
_dispatchEvent: function() {
|
|
|
if (this.classList.contains(CLASS_ACTIVE)) {
|
|
|
$.trigger(this.wrapper, 'shown', this);
|
|
|
} else {
|
|
|
$.trigger(this.wrapper, 'hidden', this);
|
|
|
}
|
|
|
},
|
|
|
_initOffCanvasVisible: function() {
|
|
|
if (!this.visible) {
|
|
|
this.visible = true;
|
|
|
if (this.offCanvasLeft) {
|
|
|
this.offCanvasLeft.style.visibility = 'visible';
|
|
|
}
|
|
|
if (this.offCanvasRight) {
|
|
|
this.offCanvasRight.style.visibility = 'visible';
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
initEvent: function() {
|
|
|
var self = this;
|
|
|
if (self.backdrop) {
|
|
|
self.backdrop.addEventListener('tap', function(e) {
|
|
|
self.close();
|
|
|
e.detail.gesture.preventDefault();
|
|
|
});
|
|
|
}
|
|
|
if (this.classList.contains($.className('draggable'))) {
|
|
|
this.wrapper.addEventListener($.EVENT_START, this); //临时处理
|
|
|
this.wrapper.addEventListener('drag', this);
|
|
|
this.wrapper.addEventListener('dragend', this);
|
|
|
}
|
|
|
this.wrapper.addEventListener('webkitTransitionEnd', this);
|
|
|
},
|
|
|
openPercentage: function(percentage) {
|
|
|
var p = percentage / 100;
|
|
|
if (!this.slideIn) {
|
|
|
if (this.offCanvasLeft && percentage >= 0) {
|
|
|
this.updateTranslate(this.offCanvasLeftWidth * p);
|
|
|
this.offCanvasLeft.classList[p !== 0 ? 'add' : 'remove'](CLASS_ACTIVE);
|
|
|
} else if (this.offCanvasRight && percentage <= 0) {
|
|
|
this.updateTranslate(this.offCanvasRightWidth * p);
|
|
|
this.offCanvasRight.classList[p !== 0 ? 'add' : 'remove'](CLASS_ACTIVE);
|
|
|
}
|
|
|
this.classList[p !== 0 ? 'add' : 'remove'](CLASS_ACTIVE);
|
|
|
} else {
|
|
|
if (this.offCanvasLeft && percentage >= 0) {
|
|
|
p = p === 0 ? -1 : 0;
|
|
|
this.updateTranslate(this.offCanvasLeftWidth * p);
|
|
|
this.offCanvasLeft.classList[percentage !== 0 ? 'add' : 'remove'](CLASS_ACTIVE);
|
|
|
} else if (this.offCanvasRight && percentage <= 0) {
|
|
|
p = p === 0 ? 1 : 0;
|
|
|
this.updateTranslate(this.offCanvasRightWidth * p);
|
|
|
this.offCanvasRight.classList[percentage !== 0 ? 'add' : 'remove'](CLASS_ACTIVE);
|
|
|
}
|
|
|
this.classList[percentage !== 0 ? 'add' : 'remove'](CLASS_ACTIVE);
|
|
|
}
|
|
|
},
|
|
|
updateTranslate: function(x) {
|
|
|
if (x !== this.lastTranslateX) {
|
|
|
if (!this.slideIn) {
|
|
|
if ((!this.offCanvasLeft && x > 0) || (!this.offCanvasRight && x < 0)) {
|
|
|
this.setTranslateX(0);
|
|
|
return;
|
|
|
}
|
|
|
if (this.leftShowing && x > this.offCanvasLeftWidth) {
|
|
|
this.setTranslateX(this.offCanvasLeftWidth);
|
|
|
return;
|
|
|
}
|
|
|
if (this.rightShowing && x < -this.offCanvasRightWidth) {
|
|
|
this.setTranslateX(-this.offCanvasRightWidth);
|
|
|
return;
|
|
|
}
|
|
|
this.setTranslateX(x);
|
|
|
if (x >= 0) {
|
|
|
this.leftShowing = true;
|
|
|
this.rightShowing = false;
|
|
|
if (x > 0) {
|
|
|
if (this.offCanvasLeft) {
|
|
|
$.each(this.offCanvasLefts, function(index, offCanvas) {
|
|
|
if (offCanvas === this.offCanvasLeft) {
|
|
|
this.offCanvasLeft.style.zIndex = 0;
|
|
|
} else {
|
|
|
offCanvas.style.zIndex = -1;
|
|
|
}
|
|
|
}.bind(this));
|
|
|
}
|
|
|
if (this.offCanvasRight) {
|
|
|
this.offCanvasRight.style.zIndex = -1;
|
|
|
}
|
|
|
}
|
|
|
} else {
|
|
|
this.rightShowing = true;
|
|
|
this.leftShowing = false;
|
|
|
if (this.offCanvasRight) {
|
|
|
$.each(this.offCanvasRights, function(index, offCanvas) {
|
|
|
if (offCanvas === this.offCanvasRight) {
|
|
|
offCanvas.style.zIndex = 0;
|
|
|
} else {
|
|
|
offCanvas.style.zIndex = -1;
|
|
|
}
|
|
|
}.bind(this));
|
|
|
}
|
|
|
if (this.offCanvasLeft) {
|
|
|
this.offCanvasLeft.style.zIndex = -1;
|
|
|
}
|
|
|
}
|
|
|
} else {
|
|
|
if (this.offCanvas.classList.contains(CLASS_OFF_CANVAS_RIGHT)) {
|
|
|
if (x < 0) {
|
|
|
this.setTranslateX(0);
|
|
|
return;
|
|
|
}
|
|
|
if (x > this.offCanvasRightWidth) {
|
|
|
this.setTranslateX(this.offCanvasRightWidth);
|
|
|
return;
|
|
|
}
|
|
|
} else {
|
|
|
if (x > 0) {
|
|
|
this.setTranslateX(0);
|
|
|
return;
|
|
|
}
|
|
|
if (x < -this.offCanvasLeftWidth) {
|
|
|
this.setTranslateX(-this.offCanvasLeftWidth);
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
this.setTranslateX(x);
|
|
|
}
|
|
|
this.lastTranslateX = x;
|
|
|
}
|
|
|
},
|
|
|
setTranslateX: $.animationFrame(function(x) {
|
|
|
if (this.scroller) {
|
|
|
if (this.scalable && this.offCanvas.parentNode === this.wrapper) {
|
|
|
var percent = Math.abs(x) / this.offCanvasWidth;
|
|
|
var zoomOutScale = 1 - (1 - this.options.scale) * percent;
|
|
|
var zoomInScale = this.options.scale + (1 - this.options.scale) * percent;
|
|
|
var zoomOutOpacity = 1 - (1 - this.options.opacity) * percent;
|
|
|
var zoomInOpacity = this.options.opacity + (1 - this.options.opacity) * percent;
|
|
|
if (this.offCanvas.classList.contains(CLASS_OFF_CANVAS_LEFT)) {
|
|
|
this.offCanvas.style.webkitTransformOrigin = '-100%';
|
|
|
this.scroller.style.webkitTransformOrigin = 'left';
|
|
|
} else {
|
|
|
this.offCanvas.style.webkitTransformOrigin = '200%';
|
|
|
this.scroller.style.webkitTransformOrigin = 'right';
|
|
|
}
|
|
|
this.offCanvas.style.opacity = zoomInOpacity;
|
|
|
this.offCanvas.style.webkitTransform = 'translate3d(0,0,0) scale(' + zoomInScale + ')';
|
|
|
this.scroller.style.webkitTransform = 'translate3d(' + x + 'px,0,0) scale(' + zoomOutScale + ')';
|
|
|
} else {
|
|
|
if (this.slideIn) {
|
|
|
this.offCanvas.style.webkitTransform = 'translate3d(' + x + 'px,0,0)';
|
|
|
} else {
|
|
|
this.scroller.style.webkitTransform = 'translate3d(' + x + 'px,0,0)';
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}),
|
|
|
getTranslateX: function() {
|
|
|
if (this.offCanvas) {
|
|
|
var scroller = this.slideIn ? this.offCanvas : this.scroller;
|
|
|
var result = $.parseTranslateMatrix($.getStyles(scroller, 'webkitTransform'));
|
|
|
return (result && result.x) || 0;
|
|
|
}
|
|
|
return 0;
|
|
|
},
|
|
|
isShown: function(direction) {
|
|
|
var shown = false;
|
|
|
if (!this.slideIn) {
|
|
|
var x = this.getTranslateX();
|
|
|
if (direction === 'right') {
|
|
|
shown = this.classList.contains(CLASS_ACTIVE) && x < 0;
|
|
|
} else if (direction === 'left') {
|
|
|
shown = this.classList.contains(CLASS_ACTIVE) && x > 0;
|
|
|
} else {
|
|
|
shown = this.classList.contains(CLASS_ACTIVE) && x !== 0;
|
|
|
}
|
|
|
} else {
|
|
|
if (direction === 'left') {
|
|
|
shown = this.classList.contains(CLASS_ACTIVE) && this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_LEFT + '.' + CLASS_ACTIVE);
|
|
|
} else if (direction === 'right') {
|
|
|
shown = this.classList.contains(CLASS_ACTIVE) && this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_RIGHT + '.' + CLASS_ACTIVE);
|
|
|
} else {
|
|
|
shown = this.classList.contains(CLASS_ACTIVE) && (this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_LEFT + '.' + CLASS_ACTIVE) || this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_RIGHT + '.' + CLASS_ACTIVE));
|
|
|
}
|
|
|
}
|
|
|
return shown;
|
|
|
},
|
|
|
close: function() {
|
|
|
this._initOffCanvasVisible();
|
|
|
this.offCanvas = this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_RIGHT + '.' + CLASS_ACTIVE) || this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_LEFT + '.' + CLASS_ACTIVE);
|
|
|
this.offCanvasWidth = this.offCanvas.offsetWidth;
|
|
|
if (this.scroller) {
|
|
|
this.offCanvas.offsetHeight;
|
|
|
this.offCanvas.classList.add(CLASS_TRANSITIONING);
|
|
|
this.scroller.classList.add(CLASS_TRANSITIONING);
|
|
|
this.openPercentage(0);
|
|
|
}
|
|
|
},
|
|
|
show: function(direction) {
|
|
|
this._initOffCanvasVisible();
|
|
|
if (this.isShown(direction)) {
|
|
|
return false;
|
|
|
}
|
|
|
if (!direction) {
|
|
|
direction = this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_RIGHT) ? 'right' : 'left';
|
|
|
}
|
|
|
if (direction === 'right') {
|
|
|
this.offCanvas = this.offCanvasRight;
|
|
|
this.offCanvasWidth = this.offCanvasRightWidth;
|
|
|
} else {
|
|
|
this.offCanvas = this.offCanvasLeft;
|
|
|
this.offCanvasWidth = this.offCanvasLeftWidth;
|
|
|
}
|
|
|
if (this.scroller) {
|
|
|
this.offCanvas.offsetHeight;
|
|
|
this.offCanvas.classList.add(CLASS_TRANSITIONING);
|
|
|
this.scroller.classList.add(CLASS_TRANSITIONING);
|
|
|
this.openPercentage(direction === 'left' ? 100 : -100);
|
|
|
}
|
|
|
return true;
|
|
|
},
|
|
|
toggle: function(directionOrOffCanvas) {
|
|
|
var direction = directionOrOffCanvas;
|
|
|
if (directionOrOffCanvas && directionOrOffCanvas.classList) {
|
|
|
direction = directionOrOffCanvas.classList.contains(CLASS_OFF_CANVAS_LEFT) ? 'left' : 'right';
|
|
|
this.refresh(directionOrOffCanvas);
|
|
|
}
|
|
|
if (!this.show(direction)) {
|
|
|
this.close();
|
|
|
}
|
|
|
}
|
|
|
});
|
|
|
|
|
|
//hash to offcanvas
|
|
|
var findOffCanvasContainer = function(target) {
|
|
|
parentNode = target.parentNode;
|
|
|
if (parentNode) {
|
|
|
if (parentNode.classList.contains(CLASS_OFF_CANVAS_WRAP)) {
|
|
|
return parentNode;
|
|
|
} else {
|
|
|
parentNode = parentNode.parentNode;
|
|
|
if (parentNode.classList.contains(CLASS_OFF_CANVAS_WRAP)) {
|
|
|
return parentNode;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
};
|
|
|
var handle = function(event, target) {
|
|
|
if (target.tagName === 'A' && target.hash) {
|
|
|
var offcanvas = document.getElementById(target.hash.replace('#', ''));
|
|
|
if (offcanvas) {
|
|
|
var container = findOffCanvasContainer(offcanvas);
|
|
|
if (container) {
|
|
|
$.targets._container = container;
|
|
|
return offcanvas;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
return false;
|
|
|
};
|
|
|
|
|
|
$.registerTarget({
|
|
|
name: name,
|
|
|
index: 60,
|
|
|
handle: handle,
|
|
|
target: false,
|
|
|
isReset: false,
|
|
|
isContinue: true
|
|
|
});
|
|
|
|
|
|
window.addEventListener('tap', function(e) {
|
|
|
if (!$.targets.offcanvas) {
|
|
|
return;
|
|
|
}
|
|
|
//TODO 此处类型的代码后续考虑统一优化(target机制),现在的实现费力不讨好
|
|
|
var target = e.target;
|
|
|
for (; target && target !== document; target = target.parentNode) {
|
|
|
if (target.tagName === 'A' && target.hash && target.hash === ('#' + $.targets.offcanvas.id)) {
|
|
|
e.detail && e.detail.gesture && e.detail.gesture.preventDefault(); //fixed hashchange
|
|
|
$($.targets._container).offCanvas().toggle($.targets.offcanvas);
|
|
|
$.targets.offcanvas = $.targets._container = null;
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
});
|
|
|
|
|
|
$.fn.offCanvas = function(options) {
|
|
|
var offCanvasApis = [];
|
|
|
this.each(function() {
|
|
|
var offCanvasApi = null;
|
|
|
var self = this;
|
|
|
//hack old version
|
|
|
if (!self.classList.contains(CLASS_OFF_CANVAS_WRAP)) {
|
|
|
self = findOffCanvasContainer(self);
|
|
|
}
|
|
|
var id = self.getAttribute('data-offCanvas');
|
|
|
if (!id) {
|
|
|
id = ++$.uuid;
|
|
|
$.data[id] = offCanvasApi = new OffCanvas(self, options);
|
|
|
self.setAttribute('data-offCanvas', id);
|
|
|
} else {
|
|
|
offCanvasApi = $.data[id];
|
|
|
}
|
|
|
if (options === 'show' || options === 'close' || options === 'toggle') {
|
|
|
offCanvasApi.toggle();
|
|
|
}
|
|
|
offCanvasApis.push(offCanvasApi);
|
|
|
});
|
|
|
return offCanvasApis.length === 1 ? offCanvasApis[0] : offCanvasApis;
|
|
|
};
|
|
|
$.ready(function() {
|
|
|
$($.classSelector('.off-canvas-wrap')).offCanvas();
|
|
|
});
|
|
|
})(mui, window, document, 'offcanvas'); |