实现拖拽列表-微信小程序

之前在网上搜索拖拽列表的实现时,发现了有好多的方法都是基于像素位置的计算实现的,这种方法要求列表元素的大小以及列表的位置有着非常严格的要求,修改和拓展起来非常的麻烦。于是我自己动手实现了一个基于页面元素定位的实现,这种方法只需要每行的高度,拓展和应用到自己的小程序里非常的简单。


 
实现效果

JS

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 }) }, }) 

WXML

<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> 

WXSS

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; } 
 


作者:HoPGoldy
链接:https://www.jianshu.com/p/d965c80fe901
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

猜你喜欢

转载自www.cnblogs.com/huangcong/p/11101817.html