微信小程序实现角度或左右滑动触发联动选项卡绝对值事件parsestringifyMathatanabsfindIndex
Posted 牧碼人
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了微信小程序实现角度或左右滑动触发联动选项卡绝对值事件parsestringifyMathatanabsfindIndex相关的知识,希望对你有一定的参考价值。
文章目录
序言
最近在写原生微信小程序项目的时候遇到了左右滑动内容更新数据,同时改变tabBar的高亮效果。于是就写了这篇文章,关于文章的css不再此文章中展示,因为都是公共的自定义类名css,所以通过类名大概就能推敲出css的值了。
1、html部分
<view class="font_size_36">
<!-- tabBar选项卡 -->
<view class="dis_r_c">
<view class="grid_c3_230 grid_row_gap_10 grid_column_gap_10">
<view class="border_777" wx:for="demoTabBar" wx:key="id">
<view class="height_90 line_height_90 text_align_center isH===item.id?'color_royalblue':''" data-item="item" catchtap="catchtapTabBar">item.title</view>
</view>
</view>
</view>
<!-- 内容 -->
<view class="margin_t_26 padding_b_36" bindtouchstart="slideStart" bindtouchmove="slideDirection" bindtouchend="slideEnd">
<view>
<view class="border_777 index!==0?'margin_t_16':''" wx:for="list" wx:key="id">
<view class="ellipsis">item.title</view>
</view>
</view>
</view>
</view>
2、javascript部分(角度滑动)
第一步:在包裹内容的最外层
HTML
标签上定义滑动事件。如果页面同时存在横向滑动的选项卡,最好不要把滑动事件绑定到页面的最外层标签上。上下左右滑动均触发的功能只适合那种类似于看小说的页面,因为看小说要么往左滑,要么往右滑,要么往下滑,要么往上滑,要么斜着滑,页面上除了返回按钮,就没有其它复杂的功能了。所以适合这个上下左右滑动均触发的模式。
bindtouchstart="slideStart"
:开始滑动。
bindtouchmove="slideDirection"
:滑动事件,只要滑动就会触发。
bindtouchend="slideEnd"
:滑动结束,即手指离开屏幕时触发。
等号前面是微信小程序提供的绑定事件的属性,等号后面是自定义的事件名。
第二步:在全局引入页面结构数据,并解构。
第三步:
data
中的变量及其作用。
demoTabBar
:选项卡数据。
originObjList
:源数据对象,存放选项卡对应的所有数据内容。
isH
:使用数据id
设置选项卡的高亮值。
list
:存储渲染列表的数据,也就是在切换选项卡时获取对应的数据值。
startX
:开始滑动的X
轴坐标值。
startY
:开始滑动的Y
轴坐标值。
direction
:滑动方向,L
向左滑,R
向右滑。
第四步:页面初始化,定义一个名为
init
的函数,并在onLoad
生命周期函数中调用init
函数来实现页面初始化。在init
函数中使用JSON
的parse
和stringify
方法克隆数据,以保证数据的完全分离状态。接着便是初始化赋值,分别是tabBar
赋值,originObjList
数据源赋值,这个数据包含所有的tabBar
类目的数据值;isH
赋值,获取tabBar
数据第一项的id
值;list
赋值,通过tabBar
的第一项数据id
获取newTabBar
中对应的值。
第五步:绑定选项卡的点击事件,事件名称为
catchtapTabBar
。在选项卡标签上自定名为item
的变量来向函数传递值。在函数中通过解构获取点击项的值,获取点击项中的id
与源数据匹配选项卡的值,最后把得到的值和id
值赋给data
中的list
和isH
两个变量。
第六步:绑定开始滑动事件,事件名称为
slideStart
。在函数中通过event
获取开始滑动的clientX
和clientY
的值。最后把值分别赋给data
中的startX
和startY
,这个值也就是开始滑动的坐标值。
第七步:绑定滑动中的事件,事件名称为
slideDirection
。在函数中通过event
获取实时滑动的坐标值,使用Math
中的atan
和PI
两个方法计算角度,通过角度的变化确定滑动的方向。Math.abs(angle) > 50
,50
这个值如果越大,方向就越不容易被改变,值越大说明需要滑动更远的距离才能改变方向,同时把方向值赋给data
中的direction
变量等待滑动结束事件使用。
第八步:绑定滑动结束事件,定义事件名为
slideEnd
。在函数中准备好数据,首先判断方向,方向分别使用L
和R
表示,也就是在滑动函数中改变的方向值。L
表示向右滑相当于上一页,R
表示向左滑相当于下一页。当方向值为L
的时候需要i < tabBarLen - 1
,当方向值为R
的时候需要i > 0
。其中tabBarLen - 1
表示已经滑动到tabBar
的最后一项,不能再向左滑动了。i > 0
表示已经滑到tabBar
的第一项,不能再向右滑动了。其中i
的值通过findIndex
方法和isH
获取当前对应tabBar
中的下标值,tabBarLen
的值就是tabBar
数据的长度。如果if
判断成立,那么就获取对应的内容赋值给list
,并且把isH
的值同时更新为当前值。如果if
条件不成立,那么就给data
中driection
变量赋值为空字符串。
const
globalData:
jsonData:
tabBar,
objList
,
showToast
= getApp();
Page(
/**
* 页面的初始数据
*/
data:
demoTabBar: [],
originObjList: [],
isH: '',
list: [],
startX: 0,
startY: 0,
direction: null
,
// 滑动结束
slideEnd()
let self = this,
selfData = self.data,
direction = selfData.direction,
tabBar = selfData.demoTabBar,
tabBarLen = tabBar.length,
originObjList = selfData.originObjList,
isH = selfData.isH,
i = tabBar.findIndex(item => item.id === isH),
id = '';
if (direction === 'R' && i > 0) // 向右滑相当于上一页
i -= 1;
else if (direction === 'L' && i < tabBarLen - 1) // 向左滑相当于下一页
i += 1;
else // 滑动不成立,清空driection
return self.setData(
direction: ''
);
id = tabBar[i].id;
self.setData(
list: originObjList[id],
isH: id
);
,
// 滑动中判断滑动方向
slideDirection( changedTouches )
let self = this,
selfData = self.data,
// 开始x坐标
startX = selfData.startX,
// 开始y坐标
startY = selfData.startY,
// 活动变化坐标
touchMoveX = changedTouches[0].clientX,
// 滑动变化坐标
touchMoveY = changedTouches[0].clientY,
direction = '',
_x = touchMoveX - startX,
_Y = touchMoveY - startY,
// Math.atan()返回数据的反正切值
// 这里算的就是角度
angle = 360 * Math.atan(_Y / _X) / (2 * Math.PI);
// 滑动角度超过50retrun
if (Math.abs(angle) > 50) return;
if (touchMoveX > startX) // 向右滑
direction = 'R';
else // 向左滑
direction = 'L';
self.setData(
direction
);
,
// 开始滑动
slideStart(e)
this.setData(
startX: e.changedTouches[0].clientX,
startY: e.changedTouches[0].clientY
);
,
// tabBar选项卡
catchtapTabBar( currentTarget: dataset: item )
let self = this,
selfData = self.data,
originObjList = selfData.originObjList;
self.setData(
list: originObjList[item.id],
isH: item.id
);
,
// 初始化
init()
let newTabBar = JSON.parse(JSON.stringify(tabBar)),
originObjList = JSON.parse(JSON.stringify(objList)),
id = newTabBar[0].id;
this.setData(
demoTabBar: newTabBar,
originObjList,
isH: id,
list: originObjList[id]
);
,
/**
* 生命周期函数--监听页面加载
*/
onLoad(options)
this.init();
,
)
3、JavaScript部分(左右滑动)
第一步:这步与上下左右滑动均触发案例的区别就是没有了滑动事件,因为不需要使用滑动事件。
第二步:这步与上下左右滑动均触发案例一样。
第三步:这步
data
中的变量与上下左右滑动均触发案例相比少了startX
、startY
和direction
三个变量。同时增加了startPageX
变量,这个变量用来记录滑动开始的pageX
值,这次获取的不再是clientX
的值。
第四步:页面初始化与上下左右滑动均触发案例相同。
第五步:绑定选项卡的点击事件与上下左右滑动均触发案例相同。
第六步:绑定开始滑动事件,事件名称为
slideStart
。在函数中通过event
获取开始滑动的pageX
值,通过parseInt
方法舍弃小数部分(这步不是必须,只是个人偏好)。最终把值赋给data
中的startPageX
变量。
第七步:绑定滑动结束事件,定义事件名为
slideEnd
。在函数中准备好数据,i
和tabBarLen
变量值的获取和作用与上下左右滑动均触发案例相同,这里不再累赘解释。定义endPageX
、slidingDistance
和direction
三个变量,endPageX
变量通过解构获取pageX
赋值,也就是滑动结束的值,同样需要parseInt
方法舍弃小数部分(这步不是必须,只是个人偏好)。slidingDistance
变量存储endPageX
(滑动结束值)和startPageX
(滑动开始值)的差值。direction
变量存储方向值,这个方向值是通过获取slidingDistance
值的第一个字符决定,如果第一个字符是减号,说明向左滑动,否则向右滑动。if (Math.abs(slidingDistance) < 100) return false;
通过Math
的abs
方法获取slidingDistance
变量的绝对值与100
比较,如果slidingDistance
的值小于100
,说明滑动距离太短,通过return
中断函数,后续代码不再执行。如果slidingDistance
的值大于100
,后续代码继续执行,执行逻辑与上下左右滑动均触发案例的第八步类似。
const
globalData:
jsonData:
tabBar,
objList
,
showToast
= getApp();
Page(
/**
* 页面的初始数据
*/
data:
demoTabBar: [],
originObjList: [],
isH: '',
list: [],
startPageX: 0
,
// 开始滑动
slideStart( changedTouches )
let pageX = changedTouches[0].pageX;
pageX = parseInt(pageX);
this.setData(
startPageX: pageX
);
,
// 滑动结束
slideEnd( changedTouches )
let self = this,
selfData = self.data,
endPageX = changedTouches[0].pageX,
tabBar = selfData.demoTabBar,
tabBarLen = tabBar.length,
originObjList = selfData.originObjList,
isH = selfData.isH,
startPageX = selfData.startPageX,
i = tabBar.findIndex(item => item.id === isH),
id = '',
slidingDistance = 0,
direction = '';
// 滑动结束,并舍弃小数点
endPageX = parseInt(endPageX);
// 滑动距离
slidingDistance = endPageX - startPageX;
// 滑动方向
direction = String(slidingDistance)[0];
if (!Math.abs(slidingDistance) > 100) return false;
if (direction === '-' && i < tabBarLen - 1) // 向左滑动
i += 1;
else if (direction !== '-' && i > 0) // 向右滑动
i -= 1;
else
return false;
id = tabBar[i].id;
self.setData(
list: originObjList[id],
isH: id
);
,
// tabBar
catchtapTabBar( currentTarget: dataset: item )
let self = this,
selfData = self.data,
originObjList = selfData.originObjList;
self.setData(
list: originObjList[item.id],
isH: item.id
);
,
// 初始化
init()
let newTabBar = JSON.parse(JSON.stringify(tabBar)),
originObjList = JSON.parse(JSON.stringify(objList)),
id = newTabBar[0].id;
this.setData(
demoTabBar: newTabBar,
originObjList,
isH: id,
list: originObjList[id]
);
,
/**
* 生命周期函数--监听页面加载
*/
onLoad(options)
this.init();
)
4、效果演示
以上是关于微信小程序实现角度或左右滑动触发联动选项卡绝对值事件parsestringifyMathatanabsfindIndex的主要内容,如果未能解决你的问题,请参考以下文章