harness/app-assets/templates/assets/js/modules/MyScroll.js (92 lines of code) (raw):
// Define the base / core Model class.
define([
'iscroll'
], function (
IScroll
) {
"use strict";
function MyScroll(elem, options) {
this.ancestor = IScroll;
this.scrollInProgress = false;
this.ancestor.apply(this, arguments);
}
MyScroll.prototype = Object.create(IScroll.prototype);
MyScroll.prototype._start = function(evt, startScroll) {
var origEvent = evt;
evt = evt.touches ? evt.touches[0] : evt;
// save position of start for later comparison
this.startPos = {
pageX: evt.pageX,
pageY: evt.pageY
};
if (startScroll) {
this.takeControlFromNative();
this.scrollInProgress = true;
this.ancestor.prototype._start.bind(this)(origEvent);
}
};
MyScroll.prototype._move = function(evt) {
if (this.startPos) {
var currentPage = this.currentPage.pageY,
currentTime,
absDx,
absDy,
origEvent = evt;
clearTimeout(this.moveTimeout);
this.moveTimeout = setTimeout(this.handleFailedSwipe.bind(this, origEvent), 50);
evt = evt.touches ? evt.touches[0] : evt;
absDx = Math.abs(evt.pageX - this.startPos.pageX);
absDy = Math.abs(evt.pageY - this.startPos.pageY);
if (this.scrollInProgress) {
this.ancestor.prototype._move.bind(this)(origEvent);
} else {
// if user is doing vertical swipe
// and is not at scroller's end
// or is at scroller's end but user is swiping up
// then start scroll
if (absDy > absDx &&
(!this.isScrollAtEnd() || (MyScroll.isElementInViewport(this.wrapper) && evt.pageY > this.startPos.pageY))) {
this._start(origEvent, true);
}
}
}
};
MyScroll.prototype._end = function(evt) {
if (this.startPos) {
clearTimeout(this.moveTimeout);
this.scrollInProgress = false;
this.ancestor.prototype._end.bind(this)(evt);
this.scrollDirection = null;
this.startPos = null;
}
};
MyScroll.prototype.takeControlFromNative = function() {
this.options.preventDefault = true;
this.options.eventPassthrough = null;
};
MyScroll.prototype.isScrollAtEnd = function() {
return this.maxScrollY === this.y;
};
MyScroll.prototype.handleFailedSwipe = function(evt) {
if (this.startPos) {
var topRange = 50;
// if last registered touch was an upward scroll
// at the top of the screen
// and there's a next page to scroll to
// then scroll to next page
if (evt.pageY < this.startPos.pageY &&
evt.pageY < topRange &&
this.pages[0][this.currentPage.pageY + 1]) {
this.scrollTo(0, this.pages[0][this.currentPage.pageY + 1].y, 500);
}
}
};
MyScroll.isElementInViewport = function(el) {
var top = el.offsetTop,
left = el.offsetLeft,
width = el.offsetWidth,
height = el.offsetHeight;
while (el.offsetParent) {
el = el.offsetParent;
top += el.offsetTop;
left += el.offsetLeft;
}
return (
top >= window.pageYOffset &&
left >= window.pageXOffset &&
(top + height) <= (window.pageYOffset + window.innerHeight) &&
(left + width) <= (window.pageXOffset + window.innerWidth)
);
};
return MyScroll;
});