小程序原生api中没有封装手势滑动组件
手势封装的思路
- 给容器绑定两个触屏事件 touchstart 和 touchend
- 用户按下屏幕事件
按下时间: Date.now() 时间戳
按下坐标: clientX 和 clientY - 用户离开屏幕事件
离开时间: Date.now()
离开坐标: clientX 和 clientY
根据两个时间运算判断用户按下屏幕时长是否合法
根据两对坐标判断距离是否合法 判断用户滑动方向
<!-- demo.vue-->
<template>
<view
@touchstart="handletouchstart"
@touchend="handletouchend"
>
demo-demo
</view>
</template>
<script>
/*
1. 给容器绑定两个触屏事件 touchstart 和 touchend
2. 用户按下屏幕事件
按下时间: Date.now() 时间戳 1970 -1-1 到现在的毫秒数
按下坐标: clientX 和 clientY
3. 用户离开屏幕事件
离开时间: Date.now()
离开坐标: clientX 和 clientY
根据两个时间运算判断用户按下屏幕时长是否合法
根据两对坐标判断距离是否合法 判断用户滑动方向
*/
export default {
data () {
return {
startTime: 0, // 按下的时间
startX: 0, // 按下x坐标
startY: 0 // 按下y坐标
}
},
methods: {
handletouchstart (event) {
console.log('按下-----')
this.startTime = Date.now()
const touch = event.changedTouches[0]
this.startX = touch.clientX
this.startY = touch.clientY
},
handletouchend (event) {
console.log('松开---------')
const endTime = Date.now();
const touch = event.changedTouches[0]
const endX = touch.clientX
const endY = touch.clientY
// 如果按下时长超过2秒则不合法不触发
if (endTime - this.startTime > 2000) return
// 滑动的方向
let direction = ''
// 判断滑动距离 如果小于10则距离不合法不触发 滑动方向 注意:要加上绝对值
console.log('绝对值', Math.abs(endX - this.startX))
// 判断滑动距离 是否合法 滑动方向 注意:要加上绝对值
if (!(Math.abs(endX - this.startX) > 10 && Math.abs(endY - this.startY < 10))) return
// 滑动方向
direction = endX - this.startX > 0 ? 'right' : 'left'
console.log(direction)
}
}
}
</script>
<style>
view {
width: 100%;
height: 500rpx;
background-color: lightblue;
}
</style>
手势封装的方法
- 在 src 根目录下新建 components目录,存放公共组件
<!-- src/components/swiperAction.vue -->
<template>
<view
@touchstart="handletouchstart"
@touchend="handletouchend"
>
<slot></slot>
</view>
</template>
<script>
export default {
data () {
return {
startTime: 0, // 按下时间
startX: 0, // 按下x坐标
startY: 0 // 按下y坐标
}
},
methods: {
handletouchstart (event) {
this.startTime = Date.now()
const touch = event.changedTouches[0]
this.startX = touch.clientX
this.startY = touch.clientY
},
handletouchend (event) {
const endTime = Date.now();
const touch = event.changedTouches[0]
const endX = touch.clientX
const endY = touch.clientY
// 如果按下时长超过2秒则不触发
if (endTime - this.startTime > 2000) return
// 滑动的方向
let direction = ''
// 判断滑动距离 如果小于10则距离不合法不触发 滑动方向 注意:要加上绝对值
if (Math.abs(endX - this.startX) < 10) return
// 滑动方向
direction = endX - this.startX > 0 ? 'right' : 'left'
this.$emit('swiperAction', {
direction }) // 向父组件中传值
}
}
}
</script>
<style>
</style>
- 自定义手势滑动组件的使用
<!-- src/pages/imgDetail/index.vue 需要左右滑动来查看图片的父组件 -->
<template>
<view>
<!-- 高清大图 开始 -->
<view class="high_img">
<!-- 3. 使用 并绑定子组件向父组件传值的自定义事件接收 direction 参数 -->
<swiper-action @swiperAction="handleSwiperAction">
<image
mode="widthFix"
:src="imgDetail.thumb"
></image>
</swiper-action>
</view>
<!-- 高清大图 结束 -->
<!-- ... -->
</template>
<script>
import swiperAction from '@/components/swiperAction.vue' // 1. 引入
export default {
components: {
swiperAction }, // 2. 注册
data () {
return {
imgDetail: [], // 图片信息对象
imgIndex: 0 // 当前图片索引
}
},
onLoad () {
// console.log(getApp().globalData)
const {
imgIndex } = getApp().globalData
this.imgIndex = imgIndex
this.getData()
},
methods: {
getData () {
// 给当前页面赋值
const {
imgList } = getApp().globalData
this.imgDetail = imgList[this.imgIndex]
this.getComments(this.imgDetail.id)
},
getComments (id) {
console.log('根据id查询当前页的其他数据', id)
},
handleSwiperAction (obj) {
// 4. 接收参数
console.log(obj) // { direction:"left" }
const direction = obj.direction
// 左滑 imgIndex ++
// 右滑 imgIndex --
// 判断数组是否越界
const {
imgList } = getApp().globalData
if (direction === 'left' && this.imgIndex < imgList.length - 1) {
this.imgIndex ++
this.getData() // 刷新数据
} else if (direction === 'right' && this.imgIndex > 0) {
this.imgIndex --
this.getData() // 刷新数据
} else {
uni.showToast({
title: '没有更多数据了', icon: 'none' })
}
}
}
}
</script>
<style lang="scss" scoped >
</style>
over
作为学习笔记记录一下,以后有好的方法再更新。