微信小程序拖动列表功能

 WXML部分

1
<view class="index"> 2 3 <!-- 数据展示区 --> 4 <scroll-view 5 class="scroll-list" 6 scroll-y 7 style="height: {{windowHeight - bottomHeight}}px" 8 bindscroll="bindscroll"> 9 <view class="scroll-item" wx:for="{{optionsList}}" wx:key="index"> 10 <view>{{item.time}}</view> 11 </view> 12 </scroll-view> 13 14 <!-- 页面可拖拽区域 --> 15 <view 16 wx:if='{{editting}}' 17 class="touchView" 18 catchtouchstart="scrollTouchStart" 19 catchtouchmove="scrollTouchMove" 20 catchtouchend="scrollTouchEnd" 21 style="height: {{windowHeight - bottomHeight}}px"> 22 </view> 23 24 <!-- 页面拖拽处理区域 --> 25 <movable-area 26 wx:if='{{editting}}' 27 class="moveable_row" 28 style="height: {{windowHeight - bottomHeight}}px"> 29 <movable-view 30 class="moveable_item {{moveData ? 'show' : 'hide'}}" 31 style="height: {{scrollItemHeight}}px;" 32 direction="vertical" 33 x="{{moveData.x}}" 34 y="{{moveData.y}}" 35 inertia="false" 36 damping="9999" 37 friction="9999" 38 > 39 <view class="scroll-item moving" hidden='{{!moveData}}'> 40 <view>{{selectItem.time}}</view> 41 </view> 42 </movable-view> 43 </movable-area> 44 45 <!-- 底部栏 --> 46 <view class="index-bottom"> 47 <button type="primary" wx:if='{{!editting}}' bindtap="changeEditing">编辑</button> 48 <button type="warn" wx:else bindtap="changeEditing">取消</button> 49 </view> 50 51 </view>
WXSS部分

1
.index { 2 position: relative; 3 } 4 5 /* 数据展示区 */ 6 .scroll-list{ 7 width: 100%; 8 } 9 .scroll-item { 10 width: 100%; 11 padding: 10rpx 20rpx; 12 box-sizing: border-box; 13 border: 1px solid #999; 14 } 15 .scroll-item.moving { 16 border: 1px dashed blue; 17 } 18 19 /* 页面可拖拽区域 */ 20 .touchView { 21 width: 100%; 22 position: absolute; 23 left: 0; 24 top: 0; 25 z-index: 1; 26 } 27 28 /* 页面拖拽处理区域 */ 29 .moveable_row { 30 width: 100%; 31 position: absolute; 32 left: 0; 33 top: 0; 34 } 35 .moveable_item { 36 width: 100%; 37 } 38 .moveable_item.show { 39 background: #fff; 40 } 41 .moveable_item.hide { 42 background: transparent; 43 } 44 45 46 /* 底部栏 */ 47 .index-bottom { 48 width: 100%; 49 display: flex; 50 justify-content: flex-end; 51 padding: 10rpx 20rpx; 52 box-sizing: border-box; 53 }
js部分  

1
Page({ 2 data:{ 3 optionsList: [], // 数据源 4 windowHeight: 0, // 屏幕高度 5 scrollItemHeight: 0, // 列表单项高度 6 bottomHeight: 0, // 底部按钮高度 7 selectItem: {}, // 当前选中元素 8 selectIndex: 0, // 当前选中索引 9 editting: true, // 是否是“编辑”状态 10 moveData: null, // 列表项移动时记录移动位置 11 scrollTop: 0 // scroll-view距离顶部距离 12 }, 13 // 初始化页面数据 14 init() { 15 this.setData({ 16 optionsList: [{time: '12:00'}, {time: '13:00'}, {time: '14:00'}, {time: '15:00'}, {time: '16:00'}, {time: '17:00'}, {time: '18:00'}, {time: '19:00'}, {time: '20:00'}, {time: '21:00'}, {time: '22:00'}, {time: '23:00'}, {time: '24:00'}, {time: '25:00'}, {time: '26:00'}, {time: '27:00'}, {time: '28:00'}, {time: '29:00'}, {time: '30:00'}, {time: '31:00'}, {time: '32:00'}, {time: '33:00'}, {time: '34:00'}, {time: '35:00'}], 17 windowHeight: wx.getSystemInfoSync().windowHeight 18 }, () => { 19 wx.createSelectorQuery().select('.index-bottom').boundingClientRect(res => { 20 this.setData({ 21 bottomHeight: res.height 22 }) 23 }).exec() 24 wx.createSelectorQuery().select('.scroll-item').boundingClientRect(res => { 25 this.setData({ 26 scrollItemHeight: res.height 27 }) 28 }).exec() 29 }); 30 }, 31 32 // 开始拖拽 33 scrollTouchStart(event) { 34 const { scrollItemHeight } = this.data 35 const firstTouchPosition = { 36 x: event.changedTouches[0].pageX, 37 y: event.changedTouches[0].pageY, 38 } 39 const { data, index } = this.getPositionDomByXY(firstTouchPosition); 40 this.setData({ 41 moveData:{ 42 x: 0, 43 y: firstTouchPosition.y - scrollItemHeight / 2 44 }, 45 selectItem: data, 46 selectIndex: index 47 }) 48 49 }, 50 51 // 拖拽ing... 52 scrollTouchMove(event) { 53 const { scrollItemHeight } = this.data 54 this.setData({ 55 moveData:{ 56 x: 0, 57 y: event.changedTouches[0].pageY - scrollItemHeight / 2 58 }, 59 }) 60 61 }, 62 63 // 拖拽结束 64 scrollTouchEnd:function (event) { 65 const { selectIndex, optionsList } = this.data 66 const endTouchPosition = { 67 x: event.changedTouches[0].pageX, 68 y: event.changedTouches[0].pageY, 69 } 70 const { index } = this.getPositionDomByXY(endTouchPosition) 71 // 交换顺序 72 const temp = optionsList[selectIndex] 73 optionsList[selectIndex] = optionsList[index] 74 optionsList[index] = temp 75 this.setData({ 76 optionsList, 77 moveData: null 78 }) 79 }, 80 81 // 根据(x,y)坐标轴获取页面元素 82 getPositionDomByXY(potions) { 83 const { scrollItemHeight, optionsList, scrollTop } = this.data 84 const y = potions.y + scrollTop; 85 const len = optionsList.length 86 for(let i = 0; i < len; i++){ 87 if(y >= i*scrollItemHeight && y < (i+1)*scrollItemHeight){ 88 // 返回匹配到的数据项 89 return { 90 data: optionsList[i], 91 index: i 92 }; 93 } 94 } 95 return y > (len-1)*scrollItemHeight ? { 96 // 匹配项位于列表之下 97 data: optionsList[len - 1], 98 index: len - 1 99 } : { 100 // 匹配项位于列表之上 101 data: optionsList[0], 102 index: 0 103 } 104 }, 105 106 // 切换编辑状态 107 changeEditing() { 108 const { editting } = this.data 109 this.setData({ editting: !editting }) 110 }, 111 112 // 监听滚动事件 113 bindscroll(e) { 114 this.data.scrollTop = e.detail.scrollTop 115 }, 116 onLoad: function () { 117 this.init() 118 }, 119 });

 

posted @ 2021-03-16 17:42  武小妞  阅读(844)  评论(0编辑  收藏  举报