[Improvement] Tabs: use touchend event to handle swipe (#695)

This commit is contained in:
张敏 2018-03-15 14:13:26 +08:00 committed by neverland
parent 5cdf3b1d79
commit e366e033ed
2 changed files with 32 additions and 27 deletions

View File

@ -72,11 +72,7 @@ export default create({
tabs: [], tabs: [],
position: 'content-top', position: 'content-top',
curActive: 0, curActive: 0,
navBarStyle: {}, navBarStyle: {}
pos: {
x: 0,
y: 0
}
}; };
}, },
@ -152,42 +148,48 @@ export default create({
swipeableHandler(init) { swipeableHandler(init) {
const swipeableEl = this.$refs.content; const swipeableEl = this.$refs.content;
this.touchMoveHandler = scrollUtils.debounce(this.watchTouchMove.bind(this), 500); (init ? on : off)(swipeableEl, 'touchstart', this.onTouchStart, false);
(init ? on : off)(swipeableEl, 'touchmove', this.onTouchMove, false);
(init ? on : off)(swipeableEl, 'touchstart', this.recordTouchStartPosition, true); (init ? on : off)(swipeableEl, 'touchend', this.onTouchEnd, false);
(init ? on : off)(swipeableEl, 'touchmove', this.touchMoveHandler, true);
}, },
// record swipe touch start position // record swipe touch start position
recordTouchStartPosition(e) { onTouchStart(event) {
this.pos = { this.startX = event.touches[0].clientX;
x: e.touches[0].clientX, this.startY = event.touches[0].clientY;
y: e.touches[0].clientY
};
}, },
// watch swipe touch move // watch swipe touch move
watchTouchMove(e) { onTouchMove(event) {
const { pos } = this; event.preventDefault();
const dx = e.touches[0].clientX - pos.x; this.deltaX = event.touches[0].clientX - this.startX;
const dy = e.touches[0].clientY - pos.y; this.direction = this.getDirection(event.touches[0]);
const isForward = dx > 0; },
const isHorizontal = Math.abs(dy) < Math.abs(dx);
// watch swipe touch end
onTouchEnd(event) {
event.preventDefault();
const { direction, deltaX, curActive } = this;
const minSwipeDistance = 50; const minSwipeDistance = 50;
/* istanbul ignore else */ /* istanbul ignore else */
if (isHorizontal && Math.abs(dx) >= minSwipeDistance) { if (direction === 'horizontal' && Math.abs(deltaX) >= minSwipeDistance) {
const active = +this.curActive;
/* istanbul ignore else */ /* istanbul ignore else */
if (isForward && active !== 0) { if (deltaX > 0 && curActive !== 0) {
this.curActive = active - 1; this.curActive = curActive - 1;
} else if (!isForward && active !== this.tabs.length - 1) { } else if (deltaX < 0 && curActive !== this.tabs.length - 1) {
this.curActive = active + 1; this.curActive = curActive + 1;
} }
} }
}, },
// get swipe direction
getDirection(touch) {
const distanceX = Math.abs(touch.clientX - this.startX);
const distanceY = Math.abs(touch.clientY - this.startY);
return distanceX > distanceY ? 'horizontal' : distanceX < distanceY ? 'vertical' : '';
},
// adjust tab position // adjust tab position
onScroll() { onScroll() {
const scrollTop = scrollUtils.getScrollTop(this.scrollEl); const scrollTop = scrollUtils.getScrollTop(this.scrollEl);

View File

@ -147,12 +147,15 @@ describe('Tabs', () => {
wrapper.vm.$nextTick(() => { wrapper.vm.$nextTick(() => {
triggerTouch(tabContent, 'touchstart', 0, 0); triggerTouch(tabContent, 'touchstart', 0, 0);
triggerTouch(tabContent, 'touchmove', -100, 0); triggerTouch(tabContent, 'touchmove', -100, 0);
triggerTouch(tabContent, 'touchend', 0, 0);
setTimeout(() => { setTimeout(() => {
expect(tabsContainer.vNode.child.curActive).to.equal(1); expect(tabsContainer.vNode.child.curActive).to.equal(1);
triggerTouch(tabContent, 'touchstart', 0, 0); triggerTouch(tabContent, 'touchstart', 0, 0);
triggerTouch(tabContent, 'touchmove', 100, 0); triggerTouch(tabContent, 'touchmove', 100, 0);
triggerTouch(tabContent, 'touchend', 0, 0);
setTimeout(() => { setTimeout(() => {
expect(tabsContainer.vNode.child.curActive).to.equal(0); expect(tabsContainer.vNode.child.curActive).to.equal(0);
done(); done();