网上有很多文章都是用movable-area
movable-view
来实现页面中的元素拖拽,这种适用于单个页面,或页面中没有其他地方使用了movable-area
movable-view
。
本文介绍的是把拖拽元素做成组件,并在组件中使用WXS提升性能,切换页面(跳转页面,返回上一页,同步元素的拖拽位置)
drag组件
首先在小程序根目录下建立components文件夹,并在此文件夹下添加一个drag组件目录如下
move.wxs:用来控制组件的在页面中的位置,也就是改变组件的CSS。只有在拖拽结束时才调用组件中的函数,记录拖拽结束的位置,到下个页面(或回退页面)时组件就能在相同的位置出现。
可以参考官方的文档:WXS响应事件
/** * move.wxs */ var safeArea;//小程序界面的安全区域 var left; var top; function init(newValue, oldValue, ownerInstance, instance) {//初始化 if (newValue) { var ins = ownerInstance.selectComponent('.drag') // 返回组件的实例 ins.setStyle({ "left": newValue.left, "top": newValue.top }); } } function handleTouchMove(e, ins) { var instance = ins.selectComponent('.drag') // 返回组件的实例 var touch = e.touches[0] || e.changedTouches[0] if (!safeArea) safeArea = instance.getDataset().area; var pageX, pageY; if (touch.clientX < safeArea.left) {//横向安全区域 pageX = safeArea.left } else if (touch.clientX > safeArea.right - 50) { pageX = safeArea.right - 50 } else { pageX = touch.clientX } if (touch.clientY < safeArea.top + 25) {//纵向安全区域 pageY = safeArea.top + 25 } else if (touch.clientY > safeArea.bottom - 150) { pageY = safeArea.bottom - 150 } else { pageY = touch.clientY } instance.setStyle({ "left": pageX + 'px', "top": pageY + 'px' }); left = pageX + 'px'; top = pageY + 'px'; return false } function handleTouchEnd(e, ins) {//移动结束 var position = { left: left, top: top } ins.callMethod('setPosition', position)//调用drag组件中的setPosition函数,存入Storage } module.exports = { handleTouchMove: handleTouchMove, handleTouchEnd: handleTouchEnd, init: init }
<!--components/drag/drag.wxml--> <wxs module="move" src="./move.wxs"></wxs> <block wx:if="{{isShow}}"> <view class="drag" data-area="{{safeArea}}" change:prop="{{move.init}}" prop="{{position}}" catchtouchmove="{{move.handleTouchMove}}" catchtouchend="{{move.handleTouchEnd}}"> </view> </block>
/** * drag.js */ const app = getApp(); let GlobalData = app.globalData Component({ /** * 组件的属性列表 */ properties: { position: Object }, attached: function () { let safeArea = GlobalData.systemInfo.safeArea || null; if (safeArea) { this.setData({ safeArea }); } }, detached: function () { // 在组件实例被从页面节点树移除时执行 }, ready: function () { }, pageLifetimes: { show: function () {//组件所在页面onshow let safeArea = this.data.safeArea || null; this.setData({ position: null }); try { let position = wx.getStorageSync('chengchema') if (!position) { position = { left: (safeArea.width - 50 - 10) + "px", top: parseInt(safeArea.height / 2 + 100) + "px" } } this.setData({ position, isShow: true }); } catch (e) { // Do something when catch error } }, hide: function () { //组件所在页面onshow this.setData({ position: null, isShow: false }) }, resize: function (size) { // 页面尺寸变化 } }, data: { safeArea: null }, /** * 组件的方法列表 */ methods: { setPosition(position) { wx.setStorage({ key: "chengchema", data: position }) } } })