mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-04-06 03:57:59 +08:00
[Improvement] add touch mixin (#869)
This commit is contained in:
parent
7285632c35
commit
bd80fe4e05
@ -23,12 +23,15 @@
|
||||
<script>
|
||||
import create from '../utils/create';
|
||||
import Clickoutside from '../utils/clickoutside';
|
||||
import Touch from '../mixins/touch';
|
||||
|
||||
const THRESHOLD = 0.15;
|
||||
|
||||
export default create({
|
||||
name: 'cell-swipe',
|
||||
|
||||
mixins: [Touch],
|
||||
|
||||
props: {
|
||||
onClose: Function,
|
||||
leftWidth: {
|
||||
@ -96,9 +99,7 @@ export default create({
|
||||
|
||||
startDrag(event) {
|
||||
this.draging = true;
|
||||
this.direction = '';
|
||||
this.startX = event.touches[0].clientX;
|
||||
this.startY = event.touches[0].clientY;
|
||||
this.touchStart(event);
|
||||
|
||||
if (this.opened) {
|
||||
this.startX -= this.offset;
|
||||
@ -106,24 +107,17 @@ export default create({
|
||||
},
|
||||
|
||||
onDrag(event) {
|
||||
const offsetTop = event.touches[0].clientY - this.startY;
|
||||
const offsetLeft = event.touches[0].clientX - this.startX;
|
||||
this.touchMove(event);
|
||||
const { deltaX } = this;
|
||||
|
||||
if ((offsetLeft < 0 && -offsetLeft > this.rightWidth) ||
|
||||
(offsetLeft > 0 && offsetLeft > this.leftWidth) ||
|
||||
(offsetLeft > 0 && !this.leftWidth) ||
|
||||
(offsetLeft < 0 && !this.rightWidth)) {
|
||||
if ((deltaX < 0 && (-deltaX > this.rightWidth || !this.rightWidth)) ||
|
||||
(deltaX > 0 && (deltaX > this.leftWidth || deltaX > 0 && !this.leftWidth))) {
|
||||
return;
|
||||
}
|
||||
|
||||
const y = Math.abs(offsetTop);
|
||||
const x = Math.abs(offsetLeft);
|
||||
const swiping = !(x < 5 || (x >= 5 && y >= x * 1.73));
|
||||
this.direction = this.direction || this.getDirection(event.touches[0]);
|
||||
|
||||
if (swiping && this.direction === 'horizontal') {
|
||||
if (this.direction === 'horizontal') {
|
||||
event.preventDefault();
|
||||
this.swipeMove(offsetLeft);
|
||||
this.swipeMove(deltaX);
|
||||
};
|
||||
},
|
||||
|
||||
@ -134,12 +128,6 @@ export default create({
|
||||
};
|
||||
},
|
||||
|
||||
getDirection(touch) {
|
||||
const offsetX = Math.abs(touch.clientX - this.startX);
|
||||
const offsetY = Math.abs(touch.clientY - this.startY);
|
||||
return offsetX > offsetY ? 'horizontal' : offsetX < offsetY ? 'vertical' : '';
|
||||
},
|
||||
|
||||
onClick(position = 'outside') {
|
||||
if (!this.offset) {
|
||||
return;
|
||||
|
@ -3,7 +3,7 @@
|
||||
v-show="value"
|
||||
class="van-image-preview"
|
||||
@touchstart="onTouchStart"
|
||||
@touchmove="onTouchMove"
|
||||
@touchmove.prevent="touchMove"
|
||||
@touchend="onTouchEnd"
|
||||
@touchcancel="onTouchEnd"
|
||||
>
|
||||
@ -20,11 +20,12 @@ import create from '../utils/create';
|
||||
import Popup from '../mixins/popup';
|
||||
import Swipe from '../swipe';
|
||||
import SwipeItem from '../swipe-item';
|
||||
import Touch from '../mixins/touch';
|
||||
|
||||
export default create({
|
||||
name: 'image-preview',
|
||||
|
||||
mixins: [Popup],
|
||||
mixins: [Popup, Touch],
|
||||
|
||||
components: {
|
||||
Swipe,
|
||||
@ -52,23 +53,14 @@ export default create({
|
||||
methods: {
|
||||
onTouchStart(event) {
|
||||
this.touchStartTime = new Date();
|
||||
this.touchStartX = event.touches[0].clientX;
|
||||
this.touchStartY = event.touches[0].clientY;
|
||||
this.deltaX = 0;
|
||||
this.deltaY = 0;
|
||||
},
|
||||
|
||||
onTouchMove(event) {
|
||||
event.preventDefault();
|
||||
this.deltaX = event.touches[0].clientX - this.touchStartX;
|
||||
this.deltaY = event.touches[0].clientY - this.touchStartY;
|
||||
this.touchStart(event);
|
||||
},
|
||||
|
||||
onTouchEnd(event) {
|
||||
event.preventDefault();
|
||||
// prevent long tap to close component
|
||||
const deltaTime = new Date() - this.touchStartTime;
|
||||
if (deltaTime < 100 && Math.abs(this.deltaX) < 20 && Math.abs(this.deltaY) < 20) {
|
||||
if (deltaTime < 100 && this.offsetX < 20 && this.offsetY < 20) {
|
||||
this.$emit('input', false);
|
||||
}
|
||||
}
|
||||
|
@ -2,8 +2,11 @@ import manager from './manager';
|
||||
import context from './context';
|
||||
import scrollUtils from '../../utils/scroll';
|
||||
import { on, off } from '../../utils/event';
|
||||
import Touch from '../touch';
|
||||
|
||||
export default {
|
||||
mixins: [Touch],
|
||||
|
||||
props: {
|
||||
// whether to show popup
|
||||
value: Boolean,
|
||||
@ -42,10 +45,6 @@ export default {
|
||||
|
||||
created() {
|
||||
this._popupId = 'popup-' + context.plusKey('id');
|
||||
this.pos = {
|
||||
x: 0,
|
||||
y: 0
|
||||
};
|
||||
},
|
||||
|
||||
mounted() {
|
||||
@ -107,7 +106,7 @@ export default {
|
||||
context.lockCount--;
|
||||
if (!context.lockCount) {
|
||||
document.body.classList.remove('van-overflow-hidden');
|
||||
off(document, 'touchstart', this.onTouchStart);
|
||||
off(document, 'touchstart', this.touchStart);
|
||||
off(document, 'touchmove', this.onTouchMove);
|
||||
}
|
||||
}
|
||||
@ -126,21 +125,11 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
onTouchStart(e) {
|
||||
this.pos = {
|
||||
x: e.touches[0].clientX,
|
||||
y: e.touches[0].clientY
|
||||
};
|
||||
},
|
||||
|
||||
onTouchMove(e) {
|
||||
const { pos } = this;
|
||||
const dx = e.touches[0].clientX - pos.x;
|
||||
const dy = e.touches[0].clientY - pos.y;
|
||||
const direction = dy > 0 ? '10' : '01';
|
||||
this.touchMove(e);
|
||||
const direction = this.deltaY > 0 ? '10' : '01';
|
||||
const el = scrollUtils.getScrollEventTarget(e.target, this.$el);
|
||||
const { scrollHeight, offsetHeight, scrollTop } = el;
|
||||
const isVertical = Math.abs(dx) < Math.abs(dy);
|
||||
|
||||
let status = '11';
|
||||
|
||||
@ -154,7 +143,7 @@ export default {
|
||||
/* istanbul ignore next */
|
||||
if (
|
||||
status !== '11' &&
|
||||
isVertical &&
|
||||
this.direction === 'vertical' &&
|
||||
!(parseInt(status, 2) & parseInt(direction, 2))
|
||||
) {
|
||||
e.preventDefault();
|
||||
|
25
packages/mixins/touch.js
Normal file
25
packages/mixins/touch.js
Normal file
@ -0,0 +1,25 @@
|
||||
export default {
|
||||
methods: {
|
||||
touchStart(event) {
|
||||
this.direction = '';
|
||||
this.deltaX = 0;
|
||||
this.deltaY = 0;
|
||||
this.offsetX = 0;
|
||||
this.offsetY = 0;
|
||||
this.startX = event.touches[0].clientX;
|
||||
this.startY = event.touches[0].clientY;
|
||||
},
|
||||
|
||||
touchMove(event) {
|
||||
const touch = event.touches[0];
|
||||
this.deltaX = touch.clientX - this.startX;
|
||||
this.deltaY = touch.clientY - this.startY;
|
||||
this.offsetX = Math.abs(this.deltaX);
|
||||
this.offsetY = Math.abs(this.deltaY);
|
||||
|
||||
if (!this.direction) {
|
||||
this.direction = this.offsetX > this.offsetY ? 'horizontal' : this.offsetX < this.offsetY ? 'vertical' : '';
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
@ -31,10 +31,13 @@
|
||||
<script>
|
||||
import create from '../utils/create';
|
||||
import scrollUtils from '../utils/scroll';
|
||||
import Touch from '../mixins/touch';
|
||||
|
||||
export default create({
|
||||
name: 'pull-refresh',
|
||||
|
||||
mixins: [Touch],
|
||||
|
||||
props: {
|
||||
pullingText: String,
|
||||
loosingText: String,
|
||||
@ -88,8 +91,7 @@ export default create({
|
||||
}
|
||||
if (this.getCeiling()) {
|
||||
this.duration = 0;
|
||||
this.startX = event.touches[0].clientX;
|
||||
this.startY = event.touches[0].clientY;
|
||||
this.touchStart(event);
|
||||
}
|
||||
},
|
||||
|
||||
@ -98,8 +100,7 @@ export default create({
|
||||
return;
|
||||
}
|
||||
|
||||
this.deltaY = event.touches[0].clientY - this.startY;
|
||||
this.direction = this.getDirection(event.touches[0]);
|
||||
this.touchMove(event);
|
||||
|
||||
if (!this.ceiling && this.getCeiling()) {
|
||||
this.duration = 0;
|
||||
@ -157,12 +158,6 @@ export default create({
|
||||
if (status !== this.status) {
|
||||
this.status = status;
|
||||
}
|
||||
},
|
||||
|
||||
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' : '';
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -23,10 +23,13 @@
|
||||
|
||||
<script>
|
||||
import create from '../utils/create';
|
||||
import Touch from '../mixins/touch';
|
||||
|
||||
export default create({
|
||||
name: 'swipe',
|
||||
|
||||
mixins: [Touch],
|
||||
|
||||
props: {
|
||||
autoplay: Number,
|
||||
loop: {
|
||||
@ -121,11 +124,8 @@ export default create({
|
||||
onTouchStart(event) {
|
||||
clearTimeout(this.timer);
|
||||
|
||||
this.deltaX = 0;
|
||||
this.direction = '';
|
||||
this.currentDuration = 0;
|
||||
this.startX = event.touches[0].clientX;
|
||||
this.startY = event.touches[0].clientY;
|
||||
this.touchStart(event);
|
||||
|
||||
if (this.active <= -1) {
|
||||
this.move(this.count);
|
||||
@ -136,19 +136,18 @@ export default create({
|
||||
},
|
||||
|
||||
onTouchMove(event) {
|
||||
this.direction = this.direction || this.getDirection(event.touches[0]);
|
||||
this.touchMove(event);
|
||||
|
||||
if (this.direction === 'horizontal') {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
this.deltaX = event.touches[0].clientX - this.startX;
|
||||
this.move(0, this.range(this.deltaX, [-this.width, this.width]));
|
||||
}
|
||||
},
|
||||
|
||||
onTouchEnd() {
|
||||
if (this.deltaX) {
|
||||
this.move(Math.abs(this.deltaX) > 50 ? (this.deltaX > 0 ? -1 : 1) : 0);
|
||||
this.move(this.offsetX > 50 ? (this.deltaX > 0 ? -1 : 1) : 0);
|
||||
this.currentDuration = this.duration;
|
||||
}
|
||||
this.autoPlay();
|
||||
@ -202,12 +201,6 @@ export default create({
|
||||
}
|
||||
},
|
||||
|
||||
getDirection(touch) {
|
||||
const offsetX = Math.abs(touch.clientX - this.startX);
|
||||
const offsetY = Math.abs(touch.clientY - this.startY);
|
||||
return offsetX > offsetY ? 'horizontal' : offsetX < offsetY ? 'vertical' : '';
|
||||
},
|
||||
|
||||
range(num, arr) {
|
||||
return Math.min(Math.max(num, arr[0]), arr[1]);
|
||||
}
|
||||
|
@ -38,10 +38,13 @@ import { raf } from '../utils/raf';
|
||||
import { on, off } from '../utils/event';
|
||||
import VanNode from '../utils/node';
|
||||
import scrollUtils from '../utils/scroll';
|
||||
import Touch from '../mixins/touch';
|
||||
|
||||
export default create({
|
||||
name: 'tabs',
|
||||
|
||||
mixins: [Touch],
|
||||
|
||||
components: {
|
||||
VanNode
|
||||
},
|
||||
@ -148,22 +151,10 @@ export default create({
|
||||
swipeableHandler(init) {
|
||||
const swipeableEl = this.$refs.content;
|
||||
|
||||
(init ? on : off)(swipeableEl, 'touchstart', this.onTouchStart, false);
|
||||
(init ? on : off)(swipeableEl, 'touchmove', this.onTouchMove, false);
|
||||
(init ? on : off)(swipeableEl, 'touchend', this.onTouchEnd, false);
|
||||
(init ? on : off)(swipeableEl, 'touchcancel', this.onTouchEnd, false);
|
||||
},
|
||||
|
||||
// record swipe touch start position
|
||||
onTouchStart(event) {
|
||||
this.startX = event.touches[0].clientX;
|
||||
this.startY = event.touches[0].clientY;
|
||||
},
|
||||
|
||||
// watch swipe touch move
|
||||
onTouchMove(event) {
|
||||
this.deltaX = event.touches[0].clientX - this.startX;
|
||||
this.direction = this.getDirection(event.touches[0]);
|
||||
(init ? on : off)(swipeableEl, 'touchstart', this.touchStart);
|
||||
(init ? on : off)(swipeableEl, 'touchmove', this.touchMove);
|
||||
(init ? on : off)(swipeableEl, 'touchend', this.onTouchEnd);
|
||||
(init ? on : off)(swipeableEl, 'touchcancel', this.onTouchEnd);
|
||||
},
|
||||
|
||||
// watch swipe touch end
|
||||
@ -172,7 +163,7 @@ export default create({
|
||||
const minSwipeDistance = 50;
|
||||
|
||||
/* istanbul ignore else */
|
||||
if (direction === 'horizontal' && Math.abs(deltaX) >= minSwipeDistance) {
|
||||
if (direction === 'horizontal' && this.offsetX >= minSwipeDistance) {
|
||||
/* istanbul ignore else */
|
||||
if (deltaX > 0 && curActive !== 0) {
|
||||
this.curActive = curActive - 1;
|
||||
@ -182,13 +173,6 @@ export default create({
|
||||
}
|
||||
},
|
||||
|
||||
// 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
|
||||
onScroll() {
|
||||
const scrollTop = scrollUtils.getScrollTop(this.scrollEl);
|
||||
|
Loading…
x
Reference in New Issue
Block a user