我正在尝试在我的移动网络应用程序中实现一个简单的自定义滚动方法。我在垂直滚动时遇到问题,如果页面被“轻弹”,我希望有一点动量效果。
问题是在拖动手势之后检测“轻弹”手势(该手势的速度和可能长度),改变方向等等。希望你明白我的意思,你可以向上或向下拖动页面,在拖动结束时,我想检测是否还有轻弹..
你如何将两者分开?这样的逻辑看起来如何?
非常感谢您的帮助。
代码:(对不起,如果这段摘录有点乱)
var Device = function() {
//define some private variablees
var startY,
startX,
startTime,
deltaY = 0,
deltaX = 0,
lastY,
currentPage,
nextPage,
prevPage,
directionY,
lastTime,
pages,
pane,
offsetX = 0,
offsetY = 0,
isPanning,
isScrolling,
isTouch = "ontouchstart" in window;
return {
init: function() {
document.getElementById('frame').addEventListener(isTouch ? 'touchstart' : 'mousedown', Device.onTouchStart, false);
//get all panes in an array
panes = document.querySelectorAll('.pane');
},
onTouchStart: function (evt) {
//get X and Y of the touch event
var touch = isTouch ? event.touches[0] : event;
startY = touch.clientY;
//add listener for touch move and end
document.addEventListener(isTouch ? 'touchmove' : 'mousemove', Device.onTouchMove, false);
document.addEventListener(isTouch ? 'touchend' : 'mouseup', Device.onTouchEnd, false);
startTime = new Date();
},
onTouchMove: function (evt) {
//get X and Y of the touch event
var touch = isTouch ? event.touches[0] : event;
currentY = touch.clientY;
//calc touch length
deltaY = currentY - startY;
//Detect if scroll is bigger than threshold 5px
if (Math.abs(deltaY) > 5 && !isPanning) {
isScrolling = true;
//get the element
pane = panes[0];
//set new position
offsetY = pane.lastOffset + deltaY;
//call animation
Device.scrollTo(pane,0,offsetY);
}
//detect last direction
directionY = (lastY >= currentY) ? 1 : 0;
//roll over last variables
lastY = currentY;
lastTime = new Date();
},
onTouchEnd: function () {
//timing
var endTime = new Date();
var velocity = (endTime - lastTime).toFixed(0);
console.log('velocity: ' + velocity);
//TEMPORARY
pane.lastOffset = offsetY;
isScrolling = false;
//housekeeping
document.removeEventListener(isTouch ? 'touchmove' : 'mousemove', Device.onTouchMove, false);
document.removeEventListener(isTouch ? 'touchend' : 'mouseup', Device.onTouchEnd, false);
//call for momentum
Device.doMomentum(velocity);
},
scrollTo: function(el,x,y) {
if (el) {
el.style['-webkit-transition-timing-function'] = '';
el.style['-webkit-transition-duration'] = '0ms';
el.style[ 'WebkitTransform' ] = 'translate3d('+x+'px,'+y+'px, 0px)';
}
},
animateTo: function(el,x,y) {
if (el) {
el.style['-webkit-transition-timing-function'] = 'cubic-bezier(0,0,0.25,1)';
el.style['-webkit-transition-duration'] = '300ms';
el.style[ 'WebkitTransform' ] = 'translate3d('+x+'px,'+y+'px, 0px)';
}
},
doMomentum: function(velocity) {
console.log((directionY == 1) ? 'up': 'down');
console.log('pane.lastOffset: ' + pane.lastOffset);
var endPosition;
if (directionY == 1) {
endPosition = pane.lastOffset - velocity;
} else {
endPosition = parseFloat(pane.lastOffset) + parseFloat(velocity);
}
console.log(endPosition);
Device.animateTo(pane,0,endPosition);
pane.lastOffset = endPosition;
}