首页 > 编程语言 >微信小程序实现长按拖拽排序

微信小程序实现长按拖拽排序

时间:2023-04-20 10:48:00浏览次数:42  
标签:index 滑块 程序实现 微信 拖拽 item let id col

<view class="container">
        <movable-area class="item_box" style="width: {{boxWeight}}rpx;height: {{boxHeight}}rpx">
          <movable-view class="item {{selectId === item.id?'item_show':'item_hide'}}" wx:for="{{healthItem}}" x="{{item.x}}rpx" y="{{item.y}}rpx" direction="all" bindchange="touchMove" bindtouchend="touchend" data-index="{{item.index}}" data-id="{{item.id}}" bindtouchstart="unlockItem">
            <view class="item_name">{{item.name}}</view>
          </movable-view>
        </movable-area>
        <view class="item_box layer_box" style="width: {{boxWeight}}rpx;height: {{boxHeight}}rpx">
          <view class="item layer_item {{selectId == item.id?'item_hide':''}}" wx:for="{{layerItem}}" style="left: {{item.x}}rpx;top: {{item.y}}rpx">
            <view class="item_name">{{item.name}}</view>
          </view>
        </view>
      </view>
Page({
  /**
   * 页面的初始数据
   */
  data: {
    arr: [
      {
        id: 1,
        name: '1号'
      },
      {
        id: 2,
        name: '2号'
      },
      {
        id: 3,
        name: '3号'
      },
      {
        id: 4,
        name: '4号'
      },
      {
        id: 5,
        name: '5号'
      },
      {
        id: 6,
        name: '6号'
      },
    ],
    boxWeight: 750, //容器宽度,100%为750,单位rpx
    boxHeight: 0, //容器高度
    height: 352, //滑块总高度,即滑块本身加上边距的高度
    selectId: 0, //当前选中滑块的id
    col: 3, //滑块列数
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onl oad: function (options) {

  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function () {
    let {arr,height,boxWeight,col,boxHeight} = this.data;
    arr.forEach((item,i) => {
      item.x = (i % col) * Math.trunc(boxWeight / col)  //区域左上角横坐标
      item.y = Math.trunc(i / col) * height //区域左上角纵坐标
      item.index = i;
    })
    if (Math.trunc(arr.length % col)){
      boxHeight = (Math.trunc(arr.length / col) + 1) * height
    }else{
      boxHeight = Math.trunc(arr.length / col) * height
    }
    this.setData({
      healthItem: arr,
      layerItem: arr,
      boxHeight,
    })
  },

  /**
   * 点击到滑块时切换隐藏显示
   */
   unlockItem(e){
    this.setData({
      selectId: e.currentTarget.dataset.id
    })
  },

  /**
   * 拖动滑块
   */
  touchMove(e){
    const s = this;
    let {boxWeight,height,layerItem,col} = s.data
    let weight = Math.trunc(boxWeight / col); //每块区域的宽度
    if (e.detail.source === 'touch'){
      let arr = [...layerItem];
      let id = e.currentTarget.dataset.id;
      let centerX = (e.detail.x * 2) + (weight / col) //当前选中滑块的中心的x坐标
      let centerY = (e.detail.y * 2) + (height / col) //当前选中滑块的中心的y坐标
      let key = 0; //滑块滑动时的位置
      let index = 0; //滑块滑动前的位置

      //通过id判断当前滑块的index
      layerItem.forEach(item => {
        if (item.id === id){
          index = item.index
        }
      })

      //根据当前滑块位置确认当前所处在哪个区域
      for (let i = 0; i < arr.length + 1; i++){
        let x1 = (i % col) * (boxWeight / col) //第n个区域的左上角和左下角x坐标
        let x2 = (i % col + 1) * (boxWeight / col) //第n个区域的右上角和右下角x坐标
        let y1 = Math.trunc(i / col) * height //第n个区域的左上角和右上角y坐标
        let y2 = Math.trunc(i / col + 1) * height //第n个区域的左下角和右下角y坐标
        //判断当前滑块所属区域
        if (centerX > x1 && centerX < x2 && centerY > y1 && centerY < y2){
          key = i
        }
      }
      //当key值大于数组长度时,即数组长度为奇数,滑块位于容器右下方无滑块的位置,滑块实际的key值为数组长度减一
      if (key >= arr.length - 1){
        key = arr.length - 1
      }

      //滑动时位置与滑动前不同时
      if (index != key){
        //计算数组中其他数据变化后的index
        arr.forEach((item,i) => {
          if (item.id != id){
            //index前进到key位置
            if (index > key){
              if (item.index >= key && item.index < index){
                item.index = item.index + 1
              }
            }
            //index后退到key位置
            if (index < key){
              if (item.index > index && item.index <= key){
                item.index = item.index - 1
              }
            }
          }else{
            item.index = key
          }
        })

        //根据数据变化后的index计算改变顺序后的实际位置
        arr.forEach((item,i) => {
          item.x = (item.index % col) * (boxWeight / col)
          item.y = Math.trunc(item.index / col) * height
        })

        s.setData({
          layerItem: arr,
          key,index
        })
      }
    }
  },

  /**
   * 停止拖动,两数组同步
   */
  touchend(e){
    let {layerItem} = this.data;
    this.setData({
      healthItem: layerItem,
    })
  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function () {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function () {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function () {

  }
})
.container {
  position: relative;
}

.item_box {
  z-index: 9;
}

.item {
  width: 200rpx;
  height: 320rpx;
  background: #FFFFFF;
  box-shadow: 0 2rpx 20rpx rgba(208, 213, 221, 0.5);
  border-radius: 10px;
  margin-bottom: 32rpx;
}

.item_name {
  width: auto;
  margin: 32rpx 32rpx 0;
  font-size: 44rpx;
  font-weight: bold;
  line-height: 60rpx;
  color: #333333;
}

.layer_box {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 1;
}

.layer_item {
  position: absolute;
  transition: left 1s, top 1s;
}

.item_show {
  opacity: 1;
}

.item_hide {
  opacity: 0;
}

代码github地址:github.com/GXYOG/wxapp-drag

  目前已知的bug: 当不停地快速拖动时,滑块位置会闪烁不定,大概是因为拖动完成后,样式还未完全渲染完毕,就开始了下一次拖动,导致滑块的index计算错误。 如果增大小程序movable-view的damping属性(默认值为20),该情况会有所改善,但滑动的动画效果不够美观。

标签:index,滑块,程序实现,微信,拖拽,item,let,id,col
From: https://www.cnblogs.com/ggqq/p/17335907.html

相关文章

  • 2023年最新微信小程序抓包教程
    01开门见山隔一个月发一篇文章,不过分。首先回顾一下《微信绑定手机号数据库被脱库事件》,我也是第一时间得知了这个消息,然后跟踪了整件事情的经过。下面是这起事件的相关截图以及近日流出的一万条数据样本:个人认为这件事也没什么,还不如关注一下之前45亿快递......
  • h5项目怎么嵌入到微信小程序中
    背景:最近用vue开发了一个h5的项目,然后产品说想把它上到微信小程序里面去,ok,开干!第一步:web-view<!--index.wxml--><viewclass="container"><web-viewsrc="https://xxx.xxxx.com/"/></view>第二步:在小程序中配置域名白名单     第三步:可以正常开发,调试啦遇......
  • vue3微信公众号商城项目实战系列(9)购物车页面
    本篇显示购物车中的商品,购物车表结构如下,我们通过接口服务抓取登录用户的购物车信息。表名字段功能shoppingcartcart_id(int)购物车编号user_id(int)用户编号goods_id(int)商品编号goods_name(varchar)商品名称photo(varchar)商品图片price(decimal)......
  • 微信小程序开发自定义tabbar
    问题背景自定义tabBar可以让开发者更加灵活地设置tabBar样式,以满足更多个性化的场景。本文将介绍微信小程序开发中如何自定义tabbar。问题分析微信小程序中,自定义tabbar的流程如下:配置信息在app.json中的tabBar项指定custom字段,同时其余tabBar相关配置也补充完整......
  • vue3微信公众号商城项目实战系列(8)商品展示页面
    本篇实现在首页展示商品功能,表结构如下:表名字段功能goodsgoods_id(int)商品编号goods_name(varchar)商品名称photo(varchar)商品图片price(decimal)价格商品表页面呈现效果如下: 第1步:在api.js中加入获取首页商品信息和加购物车的接口方法,如下......
  • 中交二公局的数字化转型之路:微信扫一扫即可轻松巡检
    中交二公局主要从事路桥施工等业务,具有公路工程施工总承包特级资质,是一家集铁路、隧道、机场、水工、市政、工程施工设计、咨询、监理等为一体的大型国有施工企业。自成立以来,中交二公局在工程施工领域积累了丰富的经验,业务范围涵盖全国各地。中交二公局的每个项目都需要用到大量的......
  • uniapp兼容微信小程序和支付宝小程序遇见的坑
    1、获取当前帐号信息getAccountInfoSync兼容;my.getOpenUserInfo 无效的授权关系微信小程序:wx.getAccountInfoSync()支付宝小程序:<buttonclass="popup-btn"@click="openAuth"type="primary"size="mini">获取</button>my.getOpenUserI......
  • 事件监听——拖拽事件drag
    在项目中遇到需要拖拽元素的需求,一开始考虑的是鼠标的mousedown、mouseup、mousemove等事件组合,之后研究发现元素本身存在drag事件,可以直接调用监听:/***添加监听事件,实现拖拽功能*/handleAddDomListen(){//具体拖拽元素constRefs=this.$refs.layouts......
  • 【uniapp】【外包杯】学习笔记day06 | 微信小程序导航栏的制作并推送的到码云【黑】
    先创建分支 格式化快捷键shift+alt+f ......
  • 微信小程序
    微信小程序小程序代码的构成项目结构1.了解项目的基本组成结构①pages用来存放所有小程序的页面②utils用来存放工具性质的模块(例如:格式化时间的自定义模块)③app.js小程序项目的入口文件④app.json小程序项目的全局配置文件⑤app.wxss小程序项目的全局样式文......