zoukankan      html  css  js  c++  java
  • 实现拖拽列表-微信小程序

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


     
    实现效果

    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%;
       100%;
    }
    
    .zhuti {
      height: 100%;
       100%;
    
      position: relative;
    }
    
    .row {
      height: 47px;
       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;
       100%;
    }
    
    .movable-row {
      box-shadow: #D9D9D9 0px 0px 20px;
    }
    
    .col1 { 
       60%;
    }
    .col2 { 
       10%;
    }
    .col3 { 
       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
    来源:简书
    简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
  • 相关阅读:
    java使用 poi导出Excel 2003异常
    ajax 提交复选框
    基于tensorflow的躲避障碍物的ai训练
    现代企业的人力资源困局
    黑暗圣经---物业公司CTO/CEO改如何给老板推荐物业信息化产品
    物业管理系统选择之困——天下有没有白吃的午餐
    江湖风云再起——全球最高性价比私有云平台解决方案发布
    ES6 promise的使用
    C# web API的初步使用!!
    post 与get的区别
  • 原文地址:https://www.cnblogs.com/huangcong/p/11101817.html
Copyright © 2011-2022 走看看