小程式拖拽排序

多芒小丸子發表於2018-05-18

需求說明

長按列表的某一行,拖拽排序。

邏輯分析

  1. 小程式的元件movable
  2. 事件touchstart、longpress、touchmove、touchend的控制
  3. 資料多時要取消掉頁面的滾動事件
  4. 陣列的重新排序
  5. 通過防抖進行優化

程式碼實現

.wxml

<view class="section">
  <scroll-view  bindlongpress='touchlong' bindtouchend='touchend' bindtouchstart='touchs' bindtouchmove='touchm' bindtouchstart='touchs' scroll-y="{{canScroll}}" bindscroll="bindscroll" style='height: 500px'>
    <movable-area style="height: {{hei}}px; width: 100%; ">
      <movable-view style="height: 60px; width: 100%; border:1px solid #000;background:rgba(0,0,0,1)" x="{{x}}" y="{{y}}" direction="vertical"  disabled="{{disabled}}" damping="{{5000}}" friction="{{1}}" hidden="{{hidden}}">
        <view>{{content}}</view>
      </movable-view>
      <view class="box">
        <view wx:for="{{data}}">{{item}}</view>
      </view>
    </movable-area>
  </scroll-view>
</view>
複製程式碼

.js

Page({
  data: {
    x: 0,
    y: 0,
    disabled: true,
    flag: false,
    data: ["111111111111111","22222222222222","333333333333","444444444444","5555555555555","666666666666","7777777777777","8888888888","999999999999999999","aaaaaaaaaaa","bbbbbbbbbbbbb","cccccccccccc","dddddddddddddd","eeeeeeeeeeee"],
    content: "",
    hidden: true,
    hei: 500,
    canScroll: true
  }, 
  onShow: function () {
    this.scrollTop = 0;
    this.setData({
      hei: this.data.data.length * 60 + 50
    })
  },
  touchlong: function(e) {
    console.log(e)
    let index = this.getIndex(e.touches[0].pageY - 40 + this.scrollTop);
    this.indexFirst = index
    this.flag = true,
    this.setData({
      x: e.touches[0].pageX + this.scrollTop,
      y: e.touches[0].pageY - 40 + this.scrollTop,
      content: this.data.data[index],
      hidden: false,
      canScroll: false
    })
  },
  bindscroll: function(e) {
    this.scrollTop = e.detail.scrollTop
    console.log(this.scrollTop)
  },
  touchs: function (e) {
    //將閉包函式儲存為區域性全域性變數
    this.f = this.debounce(this.move, 20);
  },
  //防抖-去除部分過快的操作
  debounce: function (func, wait) {
    var timeout, result;
    var args = arguments;
    return function (e) {
      var context = this;
      clearTimeout(timeout)
      timeout = setTimeout(function () {
        result = func.call(context, e)
      }, wait);
      return result;
    }
  },
  move: function (e) {
    console.log("++++++++++++++++++++++++++++++")
    this.setData({
      y: e.touches[0].pageY + this.scrollTop
    })
  },
  touchm: function (e) {
    console.log(111)
    if (this.flag) {
      this.f(e)
    }
  },
  getIndex: function(y) {
    let index = Math.ceil(y/60)
    return index;
  },
  sorter: function(index) {
    let data = this.data.data
    if (index > data.length - 1) { index = data.length - 1 }
    if (index < 0) { index = 0 }
    let indexFirst = this.indexFirst 
    //向後移動
    if(this.indexFirst < index) {
      let tem = data[indexFirst];
      for (let i = indexFirst; i < index;i ++) {
        data[i] = data[i + 1]
      }
      data[index] = tem;
    }
    //向前移動
    if (this.indexFirst > index) {
      let tem = data[indexFirst];
      for (let i = indexFirst; i > index; i--) {
        data[i] = data[i - 1]
      }
      data[index] = tem;
    }
    
    this.setData({
      data: data
    })
  },
  touchend: function (e) {
    let index = this.getIndex(e.changedTouches[0].pageY - 40 + this.scrollTop)
    if(this.flag) {
      this.sorter(index)
    }
    this.flag= false;
    this.setData({
      hidden: true,
      canScroll: true
    })
  },
})
複製程式碼

.wxss

.box view{
  height: 60px;
  font-size: 30px;
  text-align: center;
}
複製程式碼

end

第一次發文章內心有點忐忑,以後要經常總結來提升自己,前端路漫漫。

相關文章