以前在網上搜索拖拽列表的實現時,發現了有好多的方法都是基於像素位置的計算實現的,這種方法要求列表元素的大小以及列表的位置有着很是嚴格的要求,修改和拓展起來很是的麻煩。因而我本身動手實現了一個基於頁面元素定位的實現,這種方法只須要每行的高度,拓展和應用到本身的小程序裏很是的簡單。javascript
Page({
/** * 頁面的初始數據 */ data: { optionList: [], movableViewInfo: { y: 0, showClass: 'none', data: {} }, pageInfo: { rowHeight: 47, scrollHeight: 85, startIndex: null, scrollY: true, readyPlaceIndex: null, startY: 0, selectedIndex: null, } }, dragStart: function (event) { var startIndex = event.target.dataset.index console.log('獲取到的元素爲', this.data.optionList[startIndex]) // 初始化頁面數據 var pageInfo = this.data.pageInfo pageInfo.startY = event.touches[0].clientY pageInfo.readyPlaceIndex = startIndex pageInfo.selectedIndex = startIndex pageInfo.scrollY = false pageInfo.startIndex = startIndex this.setData({ 'movableViewInfo.y': pageInfo.startY - (pageInfo.rowHeight / 2) }) // 初始化拖動控件數據 var movableViewInfo = this.data.movableViewInfo movableViewInfo.data = this.data.optionList[startIndex] movableViewInfo.showClass = "inline" this.setData({ movableViewInfo: movableViewInfo, pageInfo: pageInfo }) }, dragMove: function (event) { var optionList = this.data.optionList var pageInfo = this.data.pageInfo // 計算拖拽距離 var movableViewInfo = this.data.movableViewInfo var movedDistance = event.touches[0].clientY - pageInfo.startY movableViewInfo.y = pageInfo.startY - (pageInfo.rowHeight / 2) + movedDistance console.log('移動的距離爲', movedDistance) // 修改預計放置位置 var movedIndex = parseInt(movedDistance / pageInfo.rowHeight) var readyPlaceIndex = pageInfo.startIndex + movedIndex if (readyPlaceIndex < 0 ) { readyPlaceIndex = 0 } else if (readyPlaceIndex >= optionList.length){ readyPlaceIndex = optionList.length - 1 } if (readyPlaceIndex != pageInfo.selectedIndex ) { var selectedData = optionList[pageInfo.selectedIndex] optionList.splice(pageInfo.selectedIndex, 1) optionList.splice(readyPlaceIndex, 0, selectedData) pageInfo.selectedIndex = readyPlaceIndex } // 移動movableView pageInfo.readyPlaceIndex = readyPlaceIndex // console.log('移動到了索引', readyPlaceIndex, '選項爲', optionList[readyPlaceIndex]) this.setData({ movableViewInfo: movableViewInfo, optionList: optionList, pageInfo: pageInfo }) }, dragEnd: function (event) { // 重置頁面數據 var pageInfo = this.data.pageInfo pageInfo.readyPlaceIndex = null pageInfo.startY = null pageInfo.selectedIndex = null pageInfo.startIndex = null pageInfo.scrollY = true // 隱藏movableView var movableViewInfo = this.data.movableViewInfo movableViewInfo.showClass = 'none' this.setData({ pageInfo: pageInfo, movableViewInfo: movableViewInfo }) }, /** * 生命週期函數--監聽頁面加載 */ onLoad: function (options) { var optionList = [ "段落1 內容內容內容內容內容內容內容內容內容內容內容內容內容內容內容內容", "段落2 內容內容內容內容內容內容內容內容內容內容內容內容內容內容內容內容", "段落3 內容內容內容內容內容內容內容內容內容內容內容內容內容內容內容內容", "段落4 內容內容內容內容內容內容內容內容內容內容內容內容內容內容內容內容", "段落5 內容內容內容內容內容內容內容內容內容內容內容內容內容內容內容內容", "段落6 內容內容內容內容內容內容內容內容內容內容內容內容內容內容內容內容", "段落7 內容內容內容內容內容內容內容內容內容內容內容內容內容內容內容內容", "段落8 內容內容內容內容內容內容內容內容內容內容內容內容內容內容內容內容", "段落9 內容內容內容內容內容內容內容內容內容內容內容內容內容內容內容內容" ] this.setData({ optionList: optionList }) }, })
<view class='zhuti'> <view class='row title-row' style='height: {{pageInfo.rowHeight}}px;'> <view class="col1">信息</view> <view class="col2">詳情</view> <view class="col3">排序</view> </view> <movable-area class='movable-area' style='display:{{movableViewInfo.showClass}}; height:{{pageInfo.scrollHeight}}%;'> <movable-view class='row list-row movable-row' out-of-bounds='true' damping='999' style='height:{{pageInfo.rowHeight}}px;' direction="vertical" y="{{movableViewInfo.y}}"> <view class='col1 content' >{{movableViewInfo.data}}</view> <view class="col2" > <icon type='info' color='Gray' size='22' /> </view> <view class="col3" > <icon type='download' color='Gray' size='25' /> </view> </movable-view> </movable-area> <scroll-view scroll-y='{{pageInfo.scrollY}}' style='height: {{pageInfo.scrollHeight}}%'> <block wx:for='{{optionList}}'> <view class='row list-row {{pageInfo.readyPlaceIndex == index ? "ready-place" : ""}}' style='height: {{pageInfo.rowHeight}}px;'> <view class='col1 content' >{{item}}</view> <view class="col2" > <icon type='info' color='Gray' size='22' data-index='{{index}}' bindtap='showDetail' /> </view> <view class="col3" > <icon type='download' color='Gray' size='25' data-index='{{index}}' bindtouchstart='dragStart' bindtouchmove='dragMove' bindtouchend='dragEnd' /> </view> </view> </block> </scroll-view> </view>
page { height: 100%; width: 100%; } .zhuti { height: 100%; width: 100%; position: relative; } .row { height: 47px; width: 100%; display: flex; justify-content: space-around; align-items: center; } .title-row { border-bottom: 1px solid #888888; color: #888888; } .list-row { padding: 8px 0px; border-bottom: 1px solid #D9D9D9; background-color: white; } .movable-area { position: absolute; top: 0; left: 0; z-index: 10; width: 100%; } .movable-row { box-shadow: #D9D9D9 0px 0px 20px; } .col1 { width: 60%; } .col2 { width: 10%; } .col3 { width: 10%; } .ready-place { background-color: #CCCCCC } .content { font-size: 17px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }