[improvement] SwipeCell: improve performance & fix prevent scroll

fix #1493
This commit is contained in:
rex 2019-04-09 21:34:15 +08:00 committed by GitHub
parent 4139392d35
commit 60c2bf212f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 61 additions and 61 deletions

View File

@ -1,13 +1,14 @@
export const touch = Behavior({ export const touch = Behavior({
methods: { methods: {
touchStart(event: Weapp.TouchEvent) { touchStart(event: Weapp.TouchEvent) {
const touch = event.touches[0];
this.direction = ''; this.direction = '';
this.deltaX = 0; this.deltaX = 0;
this.deltaY = 0; this.deltaY = 0;
this.offsetX = 0; this.offsetX = 0;
this.offsetY = 0; this.offsetY = 0;
this.startX = event.touches[0].clientX; this.startX = touch.clientX;
this.startY = event.touches[0].clientY; this.startY = touch.clientY;
}, },
touchMove(event: Weapp.TouchEvent) { touchMove(event: Weapp.TouchEvent) {
@ -16,7 +17,12 @@ export const touch = Behavior({
this.deltaY = touch.clientY - this.startY; this.deltaY = touch.clientY - this.startY;
this.offsetX = Math.abs(this.deltaX); this.offsetX = Math.abs(this.deltaX);
this.offsetY = Math.abs(this.deltaY); this.offsetY = Math.abs(this.deltaY);
this.direction = this.offsetX > this.offsetY ? 'horizontal' : this.offsetX < this.offsetY ? 'vertical' : ''; this.direction =
this.offsetX > this.offsetY
? 'horizontal'
: this.offsetX < this.offsetY
? 'vertical'
: '';
} }
} }
}); });

View File

@ -1,7 +1,7 @@
import { VantComponent } from '../common/component'; import { VantComponent } from '../common/component';
import { touch } from '../mixins/touch'; import { touch } from '../mixins/touch';
const THRESHOLD = 0.15; const THRESHOLD = 0.3;
VantComponent({ VantComponent({
props: { props: {
@ -20,63 +20,52 @@ VantComponent({
mixins: [touch], mixins: [touch],
data: { data: {
offset: 0, catchMove: true
draging: false
}, },
computed: { created() {
wrapperStyle() { this.offset = 0;
const { offset, draging } = this.data;
const transform = `translate3d(${offset}px, 0, 0)`;
const transition = draging ? 'none' : '.6s cubic-bezier(0.18, 0.89, 0.32, 1)';
return `
-webkit-transform: ${transform};
-webkit-transition: ${transition};
transform: ${transform};
transition: ${transition};
`;
}
}, },
methods: { methods: {
onTransitionend() {
this.swipe = false;
},
open(position: 'left' | 'right') { open(position: 'left' | 'right') {
const { leftWidth, rightWidth } = this.data; const { leftWidth, rightWidth } = this.data;
const offset = position === 'left' ? leftWidth : -rightWidth; const offset = position === 'left' ? leftWidth : -rightWidth;
this.swipeMove(offset); this.swipeMove(offset);
this.resetSwipeStatus();
}, },
close() { close() {
this.set({ offset: 0 }); this.swipeMove(0);
},
resetSwipeStatus() {
this.swiping = false;
this.opened = true;
}, },
swipeMove(offset: number = 0) { swipeMove(offset: number = 0) {
this.set({ offset }); this.offset = offset;
offset && (this.swiping = true);
!offset && (this.opened = false); const transform = `translate3d(${offset}px, 0, 0)`;
const transition = this.draging
? 'none'
: '.6s cubic-bezier(0.18, 0.89, 0.32, 1)';
this.set({
wrapperStyle: `
-webkit-transform: ${transform};
-webkit-transition: ${transition};
transform: ${transform};
transition: ${transition};
`
});
}, },
swipeLeaveTransition(direction: number) { swipeLeaveTransition() {
const { offset, leftWidth, rightWidth } = this.data; const { leftWidth, rightWidth } = this.data;
const threshold = this.opened ? 1 - THRESHOLD : THRESHOLD; const { offset } = this;
// right if (rightWidth > 0 && -offset > rightWidth * THRESHOLD) {
if (direction > 0 && -offset > rightWidth * threshold && rightWidth > 0) {
this.open('right'); this.open('right');
// left } else if (leftWidth > 0 && offset > leftWidth * THRESHOLD) {
} else if (direction < 0 && offset > leftWidth * threshold && leftWidth > 0) {
this.open('left'); this.open('left');
} else { } else {
this.swipeMove(); this.swipeMove(0);
} }
}, },
@ -85,33 +74,42 @@ VantComponent({
return; return;
} }
this.set({ draging: true }); this.draging = true;
this.startOffset = this.offset;
this.firstDirection = '';
this.touchStart(event); this.touchStart(event);
if (this.opened) {
this.startX -= this.data.offset;
}
}, },
noop() {},
onDrag(event: Weapp.TouchEvent) { onDrag(event: Weapp.TouchEvent) {
if (this.data.disabled) { if (this.data.disabled) {
return; return;
} }
this.touchMove(event); this.touchMove(event);
const { deltaX } = this;
if (!this.firstDirection) {
this.firstDirection = this.direction;
this.set({ catchMove: this.firstDirection === 'horizontal' });
}
if (this.firstDirection === 'vertical') {
return;
}
const { leftWidth, rightWidth } = this.data; const { leftWidth, rightWidth } = this.data;
const offset = this.startOffset + this.deltaX;
if ( if (
(deltaX < 0 && (-deltaX > rightWidth || !rightWidth)) || (rightWidth > 0 && -offset > rightWidth) ||
(deltaX > 0 && (deltaX > leftWidth || (deltaX > 0 && !leftWidth))) (leftWidth > 0 && offset > leftWidth)
) { ) {
return; return;
} }
if (this.direction === 'horizontal') { this.swipeMove(offset);
this.swipeMove(deltaX);
}
}, },
endDrag() { endDrag() {
@ -119,17 +117,15 @@ VantComponent({
return; return;
} }
this.set({ draging: false }); this.draging = false;
if (this.swiping) { this.swipeLeaveTransition();
this.swipeLeaveTransition(this.data.offset > 0 ? -1 : 1);
}
}, },
onClick(event: Weapp.Event) { onClick(event: Weapp.Event) {
const { key: position = 'outside' } = event.currentTarget.dataset; const { key: position = 'outside' } = event.currentTarget.dataset;
this.$emit('click', position); this.$emit('click', position);
if (!this.data.offset) { if (!this.offset) {
return; return;
} }

View File

@ -3,14 +3,12 @@
data-key="cell" data-key="cell"
catchtap="onClick" catchtap="onClick"
bindtouchstart="startDrag" bindtouchstart="startDrag"
catchtouchmove="onDrag" catchtouchmove="{{ catchMove ? 'noop' : '' }}"
capture-bind:touchmove="onDrag"
catchtouchend="endDrag" catchtouchend="endDrag"
catchtouchcancel="endDrag" catchtouchcancel="endDrag"
> >
<view <view style="{{ wrapperStyle }}">
style="{{ wrapperStyle }}"
bindtransitionend="onTransitionend"
>
<view wx:if="{{ leftWidth }}" class="van-swipe-cell__left" data-key="left" catch:tap="onClick"> <view wx:if="{{ leftWidth }}" class="van-swipe-cell__left" data-key="left" catch:tap="onClick">
<slot name="left" /> <slot name="left" />
</view> </view>