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