Skip to content

Instantly share code, notes, and snippets.

@vitalyrotari
Last active August 29, 2015 14:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vitalyrotari/f07e8e42afb16df5860f to your computer and use it in GitHub Desktop.
Save vitalyrotari/f07e8e42afb16df5860f to your computer and use it in GitHub Desktop.
jQuery Panes
/* Modernizr 2.8.2 (Custom Build) | MIT & BSD
* Build: http://modernizr.com/download/#-backgroundsize-rgba-cssanimations-csstransforms-csstransforms3d-csstransitions-touch-shiv-cssclasses-prefixed-teststyles-testprop-testallprops-prefixes-domprefixes-css_positionsticky-requestanimationframe
*/
;
window.Modernizr = (function( window, document, undefined ) {
var version = '2.8.2',
Modernizr = {},
enableClasses = true,
docElement = document.documentElement,
mod = 'modernizr',
modElem = document.createElement(mod),
mStyle = modElem.style,
inputElem ,
toString = {}.toString,
prefixes = ' -webkit- -moz- -o- -ms- '.split(' '),
omPrefixes = 'Webkit Moz O ms',
cssomPrefixes = omPrefixes.split(' '),
domPrefixes = omPrefixes.toLowerCase().split(' '),
tests = {},
inputs = {},
attrs = {},
classes = [],
slice = classes.slice,
featureName,
injectElementWithStyles = function( rule, callback, nodes, testnames ) {
var style, ret, node, docOverflow,
div = document.createElement('div'),
body = document.body,
fakeBody = body || document.createElement('body');
if ( parseInt(nodes, 10) ) {
while ( nodes-- ) {
node = document.createElement('div');
node.id = testnames ? testnames[nodes] : mod + (nodes + 1);
div.appendChild(node);
}
}
style = ['&#173;','<style id="s', mod, '">', rule, '</style>'].join('');
div.id = mod;
(body ? div : fakeBody).innerHTML += style;
fakeBody.appendChild(div);
if ( !body ) {
fakeBody.style.background = '';
fakeBody.style.overflow = 'hidden';
docOverflow = docElement.style.overflow;
docElement.style.overflow = 'hidden';
docElement.appendChild(fakeBody);
}
ret = callback(div, rule);
if ( !body ) {
fakeBody.parentNode.removeChild(fakeBody);
docElement.style.overflow = docOverflow;
} else {
div.parentNode.removeChild(div);
}
return !!ret;
},
_hasOwnProperty = ({}).hasOwnProperty, hasOwnProp;
if ( !is(_hasOwnProperty, 'undefined') && !is(_hasOwnProperty.call, 'undefined') ) {
hasOwnProp = function (object, property) {
return _hasOwnProperty.call(object, property);
};
}
else {
hasOwnProp = function (object, property) {
return ((property in object) && is(object.constructor.prototype[property], 'undefined'));
};
}
if (!Function.prototype.bind) {
Function.prototype.bind = function bind(that) {
var target = this;
if (typeof target != "function") {
throw new TypeError();
}
var args = slice.call(arguments, 1),
bound = function () {
if (this instanceof bound) {
var F = function(){};
F.prototype = target.prototype;
var self = new F();
var result = target.apply(
self,
args.concat(slice.call(arguments))
);
if (Object(result) === result) {
return result;
}
return self;
} else {
return target.apply(
that,
args.concat(slice.call(arguments))
);
}
};
return bound;
};
}
function setCss( str ) {
mStyle.cssText = str;
}
function setCssAll( str1, str2 ) {
return setCss(prefixes.join(str1 + ';') + ( str2 || '' ));
}
function is( obj, type ) {
return typeof obj === type;
}
function contains( str, substr ) {
return !!~('' + str).indexOf(substr);
}
function testProps( props, prefixed ) {
for ( var i in props ) {
var prop = props[i];
if ( !contains(prop, "-") && mStyle[prop] !== undefined ) {
return prefixed == 'pfx' ? prop : true;
}
}
return false;
}
function testDOMProps( props, obj, elem ) {
for ( var i in props ) {
var item = obj[props[i]];
if ( item !== undefined) {
if (elem === false) return props[i];
if (is(item, 'function')){
return item.bind(elem || obj);
}
return item;
}
}
return false;
}
function testPropsAll( prop, prefixed, elem ) {
var ucProp = prop.charAt(0).toUpperCase() + prop.slice(1),
props = (prop + ' ' + cssomPrefixes.join(ucProp + ' ') + ucProp).split(' ');
if(is(prefixed, "string") || is(prefixed, "undefined")) {
return testProps(props, prefixed);
} else {
props = (prop + ' ' + (domPrefixes).join(ucProp + ' ') + ucProp).split(' ');
return testDOMProps(props, prefixed, elem);
}
} tests['touch'] = function() {
var bool;
if(('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch) {
bool = true;
} else {
injectElementWithStyles(['@media (',prefixes.join('touch-enabled),('),mod,')','{#modernizr{top:9px;position:absolute}}'].join(''), function( node ) {
bool = node.offsetTop === 9;
});
}
return bool;
}; tests['rgba'] = function() {
setCss('background-color:rgba(150,255,150,.5)');
return contains(mStyle.backgroundColor, 'rgba');
};
tests['backgroundsize'] = function() {
return testPropsAll('backgroundSize');
};
tests['cssanimations'] = function() {
return testPropsAll('animationName');
};
tests['csstransforms'] = function() {
return !!testPropsAll('transform');
};
tests['csstransforms3d'] = function() {
var ret = !!testPropsAll('perspective');
if ( ret && 'webkitPerspective' in docElement.style ) {
injectElementWithStyles('@media (transform-3d),(-webkit-transform-3d){#modernizr{left:9px;position:absolute;height:3px;}}', function( node, rule ) {
ret = node.offsetLeft === 9 && node.offsetHeight === 3;
});
}
return ret;
};
tests['csstransitions'] = function() {
return testPropsAll('transition');
};
for ( var feature in tests ) {
if ( hasOwnProp(tests, feature) ) {
featureName = feature.toLowerCase();
Modernizr[featureName] = tests[feature]();
classes.push((Modernizr[featureName] ? '' : 'no-') + featureName);
}
}
Modernizr.addTest = function ( feature, test ) {
if ( typeof feature == 'object' ) {
for ( var key in feature ) {
if ( hasOwnProp( feature, key ) ) {
Modernizr.addTest( key, feature[ key ] );
}
}
} else {
feature = feature.toLowerCase();
if ( Modernizr[feature] !== undefined ) {
return Modernizr;
}
test = typeof test == 'function' ? test() : test;
if (typeof enableClasses !== "undefined" && enableClasses) {
docElement.className += ' ' + (test ? '' : 'no-') + feature;
}
Modernizr[feature] = test;
}
return Modernizr;
};
setCss('');
modElem = inputElem = null;
;(function(window, document) {
var version = '3.7.0';
var options = window.html5 || {};
var reSkip = /^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i;
var saveClones = /^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i;
var supportsHtml5Styles;
var expando = '_html5shiv';
var expanID = 0;
var expandoData = {};
var supportsUnknownElements;
(function() {
try {
var a = document.createElement('a');
a.innerHTML = '<xyz></xyz>';
supportsHtml5Styles = ('hidden' in a);
supportsUnknownElements = a.childNodes.length == 1 || (function() {
(document.createElement)('a');
var frag = document.createDocumentFragment();
return (
typeof frag.cloneNode == 'undefined' ||
typeof frag.createDocumentFragment == 'undefined' ||
typeof frag.createElement == 'undefined'
);
}());
} catch(e) {
supportsHtml5Styles = true;
supportsUnknownElements = true;
}
}());
function addStyleSheet(ownerDocument, cssText) {
var p = ownerDocument.createElement('p'),
parent = ownerDocument.getElementsByTagName('head')[0] || ownerDocument.documentElement;
p.innerHTML = 'x<style>' + cssText + '</style>';
return parent.insertBefore(p.lastChild, parent.firstChild);
}
function getElements() {
var elements = html5.elements;
return typeof elements == 'string' ? elements.split(' ') : elements;
}
function getExpandoData(ownerDocument) {
var data = expandoData[ownerDocument[expando]];
if (!data) {
data = {};
expanID++;
ownerDocument[expando] = expanID;
expandoData[expanID] = data;
}
return data;
}
function createElement(nodeName, ownerDocument, data){
if (!ownerDocument) {
ownerDocument = document;
}
if(supportsUnknownElements){
return ownerDocument.createElement(nodeName);
}
if (!data) {
data = getExpandoData(ownerDocument);
}
var node;
if (data.cache[nodeName]) {
node = data.cache[nodeName].cloneNode();
} else if (saveClones.test(nodeName)) {
node = (data.cache[nodeName] = data.createElem(nodeName)).cloneNode();
} else {
node = data.createElem(nodeName);
}
return node.canHaveChildren && !reSkip.test(nodeName) && !node.tagUrn ? data.frag.appendChild(node) : node;
}
function createDocumentFragment(ownerDocument, data){
if (!ownerDocument) {
ownerDocument = document;
}
if(supportsUnknownElements){
return ownerDocument.createDocumentFragment();
}
data = data || getExpandoData(ownerDocument);
var clone = data.frag.cloneNode(),
i = 0,
elems = getElements(),
l = elems.length;
for(;i<l;i++){
clone.createElement(elems[i]);
}
return clone;
}
function shivMethods(ownerDocument, data) {
if (!data.cache) {
data.cache = {};
data.createElem = ownerDocument.createElement;
data.createFrag = ownerDocument.createDocumentFragment;
data.frag = data.createFrag();
}
ownerDocument.createElement = function(nodeName) {
if (!html5.shivMethods) {
return data.createElem(nodeName);
}
return createElement(nodeName, ownerDocument, data);
};
ownerDocument.createDocumentFragment = Function('h,f', 'return function(){' +
'var n=f.cloneNode(),c=n.createElement;' +
'h.shivMethods&&(' +
getElements().join().replace(/[\w\-]+/g, function(nodeName) {
data.createElem(nodeName);
data.frag.createElement(nodeName);
return 'c("' + nodeName + '")';
}) +
');return n}'
)(html5, data.frag);
}
function shivDocument(ownerDocument) {
if (!ownerDocument) {
ownerDocument = document;
}
var data = getExpandoData(ownerDocument);
if (html5.shivCSS && !supportsHtml5Styles && !data.hasCSS) {
data.hasCSS = !!addStyleSheet(ownerDocument,
'article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}' +
'mark{background:#FF0;color:#000}' +
'template{display:none}'
);
}
if (!supportsUnknownElements) {
shivMethods(ownerDocument, data);
}
return ownerDocument;
}
var html5 = {
'elements': options.elements || 'abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output progress section summary template time video',
'version': version,
'shivCSS': (options.shivCSS !== false),
'supportsUnknownElements': supportsUnknownElements,
'shivMethods': (options.shivMethods !== false),
'type': 'default',
'shivDocument': shivDocument,
createElement: createElement,
createDocumentFragment: createDocumentFragment
};
window.html5 = html5;
shivDocument(document);
}(this, document));
Modernizr._version = version;
Modernizr._prefixes = prefixes;
Modernizr._domPrefixes = domPrefixes;
Modernizr._cssomPrefixes = cssomPrefixes;
Modernizr.testProp = function(prop){
return testProps([prop]);
};
Modernizr.testAllProps = testPropsAll;
Modernizr.testStyles = injectElementWithStyles;
Modernizr.prefixed = function(prop, obj, elem){
if(!obj) {
return testPropsAll(prop, 'pfx');
} else {
return testPropsAll(prop, obj, elem);
}
};
docElement.className = docElement.className.replace(/(^|\s)no-js(\s|$)/, '$1$2') +
(enableClasses ? ' js ' + classes.join(' ') : '');
return Modernizr;
})(this, this.document);
// requestAnimationFrame
// Offload animation repainting to browser for optimized performance.
// http://dvcs.w3.org/hg/webperf/raw-file/tip/specs/RequestAnimationFrame/Overview.html
// By Addy Osmani
Modernizr.addTest('raf', !!Modernizr.prefixed('requestAnimationFrame', window));// Sticky positioning - constrains an element to be positioned inside the
// intersection of its container box, and the viewport.
Modernizr.addTest('csspositionsticky', function () {
var prop = 'position:';
var value = 'sticky';
var el = document.createElement('modernizr');
var mStyle = el.style;
mStyle.cssText = prop + Modernizr._prefixes.join(value + ';' + prop).slice(0, -prop.length);
return mStyle.position.indexOf(value) !== -1;
});
;
/**
* @version 1.0.0
* @copyright 2014, TerraNet [All Rights Reserved]
* @license MIT License
* @website http://terranet.md
*/
(function ($) {
'use strict';
var CSS_TRANSITION_PROP = Modernizr.prefixed('transition');
var CSS_TRANSFORM_PROP = Modernizr.prefixed('transform');
var CSS_TRANSFORM_PROP_HYPHENATED = CSS_TRANSFORM_PROP ? hyphenated(CSS_TRANSFORM_PROP) : false;
var EVENT_TRANSITION_END = {
'WebkitTransition': 'webkitTransitionEnd',
'MozTransition': 'transitionend',
'OTransition': 'oTransitionEnd otransitionend',
'msTransition': 'MSTransitionEnd',
'transition': 'transitionend'
}[Modernizr.prefixed('transition')];
var requestAnimFrame = Modernizr.prefixed('requestAnimationFrame', window)
|| function( callback ){
window.setTimeout(callback, 1000 / 60);
};
/**
* @param {String}
* @returns {String}
*/
function hyphenated(str) {
return str.replace(/([A-Z])/g, function(str,m1){ return '-' + m1.toLowerCase(); }).replace(/^ms-/,'-ms-');
}
/**
* @param {Event} event
*/
function eventStop(event) {
event && event.preventDefault();
}
/**
* @param {Event} event
* @param {Number?} speed
* @returns {Number}
*/
function eventWheelDelta(event, speed) {
var e = event.originalEvent ? event.originalEvent : window.event;
var delta = 0;
if (!isNum(speed)) {
speed = 20;
}
if ('deltaX' in e) {
var multiply = (e.deltaMode === 1) ? speed : 1;
delta = -e.deltaY * multiply;
} else if ('wheelDeltaX' in e) {
delta = e.wheelDeltaY / 120 * speed;
} else if ('wheelDelta' in e) {
delta = e.wheelDelta / 120 * speed;
} else if ('detail' in e) {
delta = -e.detail / 3 * speed;
}
return delta;
}
/**
* @param {HTMLElement} el
* @param {Object} exceptions
* @returns {boolean}
*/
function preventDefaultException(el, exceptions) {
for (var i in exceptions) {
if (exceptions.hasOwnProperty(i) && exceptions[i].test(el[i])) {
return true;
}
}
return false;
}
/**
* @param {Event} event
* @param {String?} eventName
*/
function dispatchEventTap(event, eventName) {
var newEvent = document.createEvent('Event');
newEvent.initEvent(eventName || 'tap', true, true);
newEvent.pageX = event.pageX;
newEvent.pageY = event.pageY;
event.target.dispatchEvent(newEvent);
}
/**
* @param {Event} event
*/
function dispatchEventClick(event) {
var target = event.target;
var newEvent;
if ( !(/(SELECT|INPUT|TEXTAREA)/i).test(target.tagName) ) {
newEvent = document.createEvent('MouseEvents');
newEvent.initMouseEvent('click', true, true, event.view, 1,
target.screenX, target.screenY, target.clientX, target.clientY,
event.ctrlKey, event.altKey, event.shiftKey, event.metaKey,
0, null);
newEvent._constructed = true;
target.dispatchEvent(newEvent);
}
}
/**
* @param {*} n
* @returns {boolean}
*/
function isNum(n) {
return typeof n === 'number' && !isNaN(n);
}
//
var REGEXP_UP_KEYS = /33|36|38/;
var REGEXP_DOWN_KEYS = /32|34|35|40/;
var REGEXP_INPUTS = /input|textarea/i;
var CLASS_CURRENT = 'pane-current';
var CLASS_SCROLLABLE = 'pane-scrollable';
var CLASS_TOP = 'pane-top';
var CLASS_MOVE = 'pane-move';
var isBadAndroid = /Android /.test(window.navigator.appVersion) && !(/Chrome\/\d/.test(window.navigator.appVersion));
function attachIScroll(Panes, el, options) {
var scroll = new IScroll(el, options);
scroll.on('scrollStart', function() {
Panes.onScrollStart(this);
});
scroll.on('scrollEnd', function() {
Panes.onScrollEnd(this);
});
return scroll;
}
var Panes = $.Panes = {};
/**
* Default options
*
* @type {{wheel: {enabled: boolean, quietPeriod: number}, scroll: {bounceEasing: string, bounceTime: number, click: boolean, disableMouse: boolean, mouseWheel: boolean, scrollbars: string, resizeScrollbars: boolean}}}
*/
Panes.options = {
wheel: {
enabled: true,
quietPeriod: 400
},
scroll: {
bounceEasing: 'back',
bounceTime: 500,
click: true,
disableMouse: true,
mouseWheel: true,
scrollbars: 'custom',
resizeScrollbars: true,
keyBindings: {
pageUp: 33,
pageDown: 34,
end: 35,
home: 36,
left: 37,
up: 38,
right: 39,
down: 40,
space: 32
}
},
preventDefaultException: {
tagName: /^(INPUT|TEXTAREA|BUTTON|SELECT)$/
}
};
Panes.isBlocked_ = false;
Panes.scroll_ = {};
Panes.touch_ = {
start: {},
delta: {},
pending: undefined,
moved: false
};
Panes.init = function() {
this.$pane = $('.panes');
this.$panes = this.$pane.children('.pane');
var len = this.$panes.length;
if (!len) {
return;
}
this.isPending = false;
this.last = len-1;
this.paneStyles_ = new Array(len);
this.panePositions_ = new Array(len);
this.paneScrolls_ = new Array(len);
this.$panes.each(function(index, el) {
var $el = $(el);
if ($el.hasClass(CLASS_CURRENT)) {
this.current = index;
}
this.paneStyles_[index] = $el.attr('style');
this.paneScrolls_[index] = $el.hasClass(CLASS_SCROLLABLE)
? attachIScroll(this, el, this.options.scroll)
: undefined;
}.bind(this));
if (!isNum(this.current)) {
this.current = 0;
this.$panes
.eq(this.current)
.addClass(CLASS_CURRENT)
.trigger('pane:in', [this.current, this])
.trigger('pane:on', [this.current, this]);
}
this.updatePaneSize();
this.updatePanesPositions();
this.attachEventListeners_();
};
Panes.block = function() {
this.isBlocked_ = true;
};
Panes.unblock = function() {
this.isBlocked_ = false;
};
Panes.isBlocked = function() {
return this.isBlocked_;
};
Panes.updatePaneSize = function() {
var $pane = this.$panes.eq(0);
this.paneSize_ = {
x: $pane.width(),
y: $pane.height()
};
};
Panes.updatePanesPositions = function() {
this.$panes.each(function(index) {
this.panePositions_[index] = this.current === index
? 0
: this.current < index ? this.paneSize_.y : -this.paneSize_.y;
}.bind(this));
};
Panes.next = function(event) {
if (!this.isLast() && !this.isBlocked()) {
var index = this.current+1;
if (!this.hasIScroll(index)) {
eventStop(event);
}
this.move(index, this.panePositions_[index], 50);
}
};
Panes.prev = function(event) {
if (!this.isFirst() && !this.isBlocked()) {
var index = this.current-1;
if (!this.hasIScroll(index)) {
eventStop(event);
}
this.move(index, this.panePositions_[index], 50);
}
};
/**
* @param {Number} index
*/
Panes.to = function(index) {
if (!this.isCurrent(index) && !this.isBlocked()) {
this.move(index, this.panePositions_[index], 50);
}
};
/**
* @param {Number} index
* @param {Number?} dist
* @param {Number?} delay
*/
Panes.move = function(index, dist, delay) {
if (this.isPending || this.isBlocked() || index < 0 || index > this.last) {
return;
}
this.isPending = true;
this.previous = this.current;
this.current = index;
var $prev = this.$panes.eq(this.previous);
var $current = this.$panes.eq(this.current)
.addClass(CLASS_CURRENT + ' ' + CLASS_TOP);
var jobs = 0;
var timer;
var complete = function() {
jobs++;
if (jobs < 2) {
return;
}
if (this.scroll) {
this.scroll.scrollTo(0, this.current > this.previous ? this.scroll.maxScrollY : 0, 0);
}
$prev.removeClass(CLASS_CURRENT).trigger('pane:off', [this.previous, this]);
$current.trigger('pane:on', [this.current, this]);
timer = setTimeout(function() {
this.isPending = false;
}.bind(this), 0);
}.bind(this);
var animate = function() {
$prev.trigger('pane:out', [this.previous, this]);
$current.trigger('pane:in', [this.current, this]);
this.translate(this.current, 0, 600, 'ease', 0, complete);
this.translate(this.previous, this.previous < this.current ? -this.paneSize_.y : this.paneSize_.y, 600, 'ease', delay || 0, complete);
this.updatePanesPositions();
}.bind(this);
if (isNum(dist)) {
if (Modernizr.cssanimations) {
if (Modernizr.csstransforms3d) {
var transform = 'translate3d(0,' + dist + 'px,0)';
} else {
transform = 'translateY(' + dist + 'px) translateZ(0)';
}
$current.css(CSS_TRANSFORM_PROP, transform);
} else {
$current.css('top', dist + 'px');
}
requestAnimFrame(animate)
} else {
animate();
}
};
/**
* @param {Number} index
* @param {Number} dist
* @param {Number?} speed
* @param {String?} easing
* @param {Number?} delay
* @param {Function?} callback
*/
Panes.translate = function(index, dist, speed, easing, delay, callback) {
var $pane = this.$panes.eq(index);
var transform;
if (!$pane.length) {
return;
}
if (speed) {
var complete = function() {
this.lastMoveIndex_ = undefined;
$pane.removeClass(CLASS_MOVE + ' ' + CLASS_TOP);
var styles = this.paneStyles_[index];
if (styles) {
$pane.attr('style', styles);
} else {
$pane.removeAttr('style');
}
if ($.isFunction(callback)) {
callback();
}
}.bind(this);
if (Modernizr.cssanimations) {
var props = {};
if (Modernizr.csstransforms3d) {
transform = 'translate3d(0,' + dist + 'px,0)';
} else {
transform = 'translateY(' + dist + 'px) translateZ(0)';
}
props[CSS_TRANSFORM_PROP] = transform;
props[CSS_TRANSITION_PROP] = CSS_TRANSFORM_PROP_HYPHENATED +
' ' + (speed / 1000) + 's' +
' ' + (easing || 'ease');
if (delay > 0) {
props[CSS_TRANSITION_PROP] += ' ' + (delay / 1000) + 's';
}
$pane.one(EVENT_TRANSITION_END, complete);
requestAnimFrame(function() {
$pane.css(props);
});
} else {
if (!$.easing[easing]) {
easing = 'swing';
}
if (delay > 0) {
$pane.delay(delay);
}
$pane.animate({ top: dist + 'px' }, speed, easing, complete);
}
} else {
if (Modernizr.csstransforms) {
if (Modernizr.csstransforms3d) {
transform = 'translate3d(0,' + dist + 'px, 0)';
} else {
transform = 'translateY(' + dist + 'px) translateZ(0)';
}
$pane.css(CSS_TRANSFORM_PROP, transform);
} else {
$pane.css('top', dist + 'px');
}
if ($.isFunction(callback)) {
callback();
}
}
};
/**
* @returns {boolean}
*/
Panes.isCurrent = function(index) {
return index === this.current;
};
/**
* @returns {boolean}
*/
Panes.isFirst = function() {
return this.current === 0;
};
/**
* @returns {boolean}
*/
Panes.isLast = function() {
return this.current === this.last;
};
/**
* @param {Number} index
* @returns {boolean}
*/
Panes.hasIScroll = function(index) {
return (window.IScroll && this.paneScrolls_[index] instanceof IScroll);
};
/**
*
* @param {Number} index
* @returns {IScroll}
*/
Panes.getIScroll = function(index) {
return this.paneScrolls_[index];
};
/**
*
* @param {TouchEvent} event
*/
Panes.onTouchStart = function(event) {
if (!this.scroll
&& !isBadAndroid
&& !preventDefaultException(event.target, this.options.preventDefaultException)) {
event.preventDefault();
}
var touches = event.touches[0];
this.touch_.start = {
x: touches.pageX,
y: touches.pageY,
time: +new Date
};
this.touch_.moved = false;
this.touch_.pending = undefined;
};
/**
* @param {TouchEvent} event
*/
Panes.onTouchMove = function(event) {
var isValid;
this.touch_.moved = true;
if (this.scroll) {
isValid = (this.scroll_.dirY < 0 && this.scroll_.y === 0)
|| (this.scroll_.dirY > 0 && this.scroll_.y === this.scroll_.maxY);
if (!isValid) {
return;
}
} else {
if (event.touches.length > 1 || event.scale && event.scale !== 1) {
return;
}
}
var touches = event.touches[0];
var delta = this.touch_.delta = {
x: touches.pageX - this.touch_.start.x,
y: touches.pageY - this.touch_.start.y
};
var distanceX = Math.abs(delta.x);
var distanceY = Math.abs(delta.y);
// determine if scrolling test has run - one time test
if (!this.touch_.pending) {
this.touch_.pending = !!(this.touch_.pending || distanceY < distanceX);
}
if (!this.touch_.pending) {
if (!this.scroll) {
event.preventDefault();
}
delta.y =
delta.y /
((!this.current && delta.y > 0 // if first slide and sliding left
|| this.current === this.last // or if last slide and sliding right
&& delta.y < 0 // and if sliding at all
) ?
(distanceY / this.paneSize_.y + 1) // determine resistance level
: 1); // no resistance if false
isValid = !(delta.y < 0 ? this.isLast() : this.isFirst());
var next = delta.y < 0 ? this.current+1 : this.current-1;
if (!isValid) {
return;
}
if (next !== this.lastMoveIndex_) {
this.$panes.eq(next).addClass(CLASS_MOVE);
}
this.translate(next, this.panePositions_[next] + delta.y, 0);
if (!this.scroll) {
this.translate(this.current, (delta.y / 2), 0);
}
this.lastMoveIndex_ = next;
}
};
/**
* @param {TouchEvent} event
*/
Panes.onTouchEnd = function(event) {
if (!this.touch_.moved) {
dispatchEventTap(event, 'tap');
dispatchEventClick(event);
return;
}
if (!this.touch_.delta.y) {
return;
}
var duration = +new Date - this.touch_.start.time;
var delta = this.touch_.delta;
var dist = Math.abs(delta.y);
var isValidSlide =
Number(duration) < 250 // if slide duration is less than 250ms
&& dist > 20 // and if slide amt is greater than 20px
|| dist > this.paneSize_.y / 2; // or if slide amt is greater than half the width
if (!this.touch_.pending) {
var direction = delta.y < 0;
if (isValidSlide) {
if (direction) {
if (!this.isLast()) {
this.move(this.current+1);
}
} else {
if (!this.isFirst()) {
this.move(this.current-1);
}
}
} else {
var index = direction ? this.current+1 : this.current-1;
this.translate(index, this.panePositions_[index], 700);
if (!this.scroll) {
this.translate(this.current, this.panePositions_[this.current], 600);
}
}
}
this.lastMoveIndex_ = undefined;
this.touch_.delta = {};
};
/**
* @param {IScroll} event
*/
Panes.onScrollStart = function(event) {
this.scroll_ = {
x: event.x,
y: event.y,
maxY: event.maxScrollY,
dirX: event.directionX,
dirY: event.directionY
};
};
/**
* @param event
*/
Panes.onScrollEnd = function(event) {
if (event.isMouseWheel) {
var isValid = (event.directionY < 0 && this.scroll_.y === 0)
|| (event.directionY > 0 && this.scroll_.y === event.maxScrollY);
if (isValid) {
if (event.directionY < 0) {
this.prev();
} else {
this.next();
}
}
}
};
Panes.attachEventListeners_ = function() {
this.$pane.on('pane:on', '.pane', function(event, index) {
this.scroll = this.paneScrolls_[index] || undefined;
}.bind(this));
var $body = $('body');
$body.on('keypress keydown', function(event) {
var isFormElement = REGEXP_INPUTS.test(event.target.tagName);
var key = event.which;
if (isFormElement && /32|38|40/.test(key)) {
return;
}
if (REGEXP_UP_KEYS.test(key)) { // Up
if (this.scroll) {
if (this.scroll.y >= 0) {
this.prev(event);
}
} else {
this.prev(event);
}
} else if (REGEXP_DOWN_KEYS.test(key)) { // Down
if (this.scroll) {
if (Math.abs(this.scroll.y) >= Math.abs(this.scroll.maxScrollY)) {
this.next(event);
}
} else {
this.next(event);
}
}
}.bind(this));
if (Panes.options.wheel.enabled) {
$body.on('wheel mousewheel DOMMouseScroll', function(event) {
if (this.scroll) {
return;
}
var now = new Date().getTime();
if (this.options.wheel.quietPeriod > 0 && (now - this.wheelLastSeen_ < this.options.wheel.quietPeriod)) {
eventStop(event);
} else {
var delta = eventWheelDelta(event);
if (delta < 0) { // Down
this.next(event);
} else if (delta > 0) { // Up
this.prev(event);
}
this.wheelLastSeen_ = now;
}
}.bind(this));
}
$(document).on('touchstart touchmove touchend touchcancel', function(event) {
var originalEvent = event.originalEvent ? event.originalEvent : event;
if (this.isPending) {
originalEvent.preventDefault();
return;
}
switch (event.type) {
case 'touchstart':
this.onTouchStart(originalEvent);
break;
case 'touchmove':
this.onTouchMove(originalEvent);
break;
case 'touchend':
case 'touchcancel':
this.onTouchEnd(originalEvent);
break;
}
}.bind(this));
};
}(jQuery));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment