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

作者: HoPGoldy | 来源:发表于2018-10-18 23:38 被阅读5次

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


    实现效果

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

    相关文章

      网友评论

        本文标题:实现拖拽列表-微信小程序

        本文链接:https://www.haomeiwen.com/subject/qqyezftx.html