锲子
微信小程序自定义左滑功能加上跳转,换成以往,左滑功能的逻辑一般是在js中实现,但在拖动方面,性能并不是那么的流畅。如今,官方新扩展了一套脚本语言wxs,在IOS设备上运行,性能会比JS快2~20倍,至于安卓上运行效率无差异。
构思
结合wxs,做左滑功能主要分为三个步骤:拖动开始=>拖动中=>拖动结束
让我们看看,这三个步骤需要做好哪些工作?
拖动开始
- 获取触发事件点的坐标数据
- 将坐标数据存到组件中,“拖动中”和“拖动结束”这两步骤要用上
拖动中
- 拿到拖动开始时存储的坐标数据
- 获取每一个拖动点的坐标数据,计算出与拖动开始的坐标数据的横坐标之差
- 根据计算出的横坐标之差加上当前左滑的距离,设置该组件的样式
拖动结束
- 拿到拖动开始时存储的坐标数据
- 获取离开时触发点的坐标数据,计算出与拖动开始的坐标数据的横坐标之差
- 根据计算出的结果,判断拖动是向左还是向右?最好设置好该组件的样式
代码片段
index.wxs
// 拖动开始时的事件 function lwstart(event,ins){ console.log("拖动开始"); // 获取事件触发点的坐标数据 var touch = event.touches[0] || event.changedTouches[0] //存储坐标数据,后期使用 var moveE = ins.getState(); moveE.startX = touch.pageX; moveE.startY = touch.pageY; //默认左滑当前的距离,也要存储起来 if (!moveE.rX) { moveE.rX = 0; } } // 拖动中时的事件 function lwmove(event, ins) { //获取到该组件的id var id = event.currentTarget.dataset.id; //组件实例 var node = ins.selectComponent(id); if(node){ // 获取拖动点的坐标数据 var touch = event.touches[0] || event.changedTouches[0] //拿出拖动开始时存储的数据 var moveE = ins.getState(); //计算拖动点与拖动开始时的触发点之间的横坐标之差 var gap = touch.pageX - moveE.startX; //获取左滑的距离(拖动中不存储这个数据,而是拖动结束来存储这个数据) var left = moveE.rX; //为向左滑动做处理,开始设置左滑的距离 if (gap < 0) { // 设置组件向左滑的距离 node.setStyle({ "transform": "translateX(" + (gap + left) + "px)" }) } console.log("拖动中", (gap + left)); } } // 拖动结束时的事件 function lwend(event, ins) { console.log("拖动结束"); //获取到该组件的id var id = event.currentTarget.dataset.id; //组件实例 var node = ins.selectComponent(id); if(node){ // 获取离开点的坐标数据 var touch = event.touches[0] || event.changedTouches[0] //拿出拖动开始时存储的数据 var moveE = ins.getState(); var x = touch.pageX; //计算拖动点与拖动开始时的触发点之间的横坐标之差 var gap = x - moveE.startX; //重新设置左滑的距离(最大是左滑区域的宽度:80,最小是0) //根据算出来的数据判断是右滑还是左滑? console.log(gap, "gggg"); if (Math.floor(gap) == 0||Math.floor(gap)==-1) { console.log("调用导航方法"); //跟点击事件差不多了 // 调用js里的方法跳转就行 ins.callMethod('navfn', { id: id }) } else if (gap < 0) { // 左滑 // 设置左滑最大距离 node.setStyle({ "transform": "translateX(-80px)" }) // 存储左滑距离 moveE.rX = -80; } else if (gap > 0) { //右滑 //设置左滑最小距离 node.setStyle({ "transform": "translateX(0px)" }) // 存储左滑距离 moveE.rX = 0; } } } module.exports={ lwstart:lwstart, lwmove:lwmove, lwend:lwend }
index.wxml
<!-- 导入wxs --> <wxs module="test" src="./index.wxs"></wxs> <!-- 作者有点懒,样式全是内联样式 --> <!-- 我设置了两种组件的具体宽度(屏幕宽度和左滑宽度) --> <!-- 不允许横向滚动 --> <scroll-view style="{{ww}}px;"> <view wx:for="{{2}}" style="margin:10px 0;display:flex;align-items:center;{{ww+80}}px;transition:transform .3s;" bindtouchstart="{{test.lwstart}}" bindtouchmove="{{test.lwmove}}" bindtouchend="{{test.lwend}}" id="move{{index}}" data-id="#move{{index}}"> <!-- 内容区域 --> <view class="con" style="{{ww}}px;height:80px;background-color:blue;"> </view> <!-- 左滑区域 --> <view class="left" style="80px;height:60px;background-color:red;"> </view> </view> </scroll-view>
index..js
let that; Page({ data: { ww:400 }, onLoad: function () { that=this; wx.getSystemInfo({ success: function(res) { that.setData({ ww:res.windowWidth }) }, }) }, navfn(e){ console.log(e,"跳转"); wx.navigateTo({ url: '../nav/nav?id='+e.id, }) } })
预览效果