jstang博客

时间:

  • 首页
  • zblog作品
  • 前端笔记
  • python
  • seo
  • cms
    • zblog
    • 帝国cms
  • 杂记

当前位置:

  • 首页
  • 前端笔记

微信小程序拖拽排序

发布时间:2022-07-26

作者: jstang

2160 0

微信小程序拖拽排序


问题:拖拽区域,在非拖拽时候 ,进行 手势上下滑动


思路一:每个所需要排序的view,增加 排序 ico 按钮,点击后,拖拽取件生效,反之,禁止


.wxss文件

movable-view {

    pointer-events: auto;

}


movable-area {

    pointer-events: none;

}

父级 pointer-events: none;  父级设置 禁用鼠标手势事件,,即可实现上下滑动


子级(需要鼠标,手势事件的区域) 设置为 pointer-events: auto;




思路二: 判断手势 上下滑动,如果上下滑动,拖拽取件 禁止,默认生效


。。官方没找到  上下左右滑动

image.png

 <movable-area class="movable-container wx:if='{{movale_ok == 1 ? 'area_events' : 'area_events_auto'}}'" style="height: {{ elementHeight * list.length + 40 * list.length }}px;" catch:touchmove="onHackTouchMove">

        <block wx:for="{{ list }}" wx:key="index">

            <view class="index_view {{ dragElement && dragElement.id === item.id ? 'item--tran' : '' }} {{ lastTarget === index ? 'item--target' : '' }}" data-index="{{ index }}" bind:longpress="onLongPress" bind:touchmove="onTouchMove" bind:touchend="onTouchEnd">


                <view class="index_view_p">

                    <text>{{ item.bj_title }}</text>

                    <text>当前进度:{{ item.jidnu }}</text>

                    <text>{{ item.zhouqi }}</text>

                    <text bindtap="on_student">{{ item.renshu }}名学员--查看</text>

                </view>

                <view class="column_view_index">

                    <van-icon name="bars" size='45rpx' style="align-self:flex-end;" data-index="{{ index }}" bind:longpress="onLongPress" bind:touchmove="onTouchMove" bind:touchend="onTouchEnd" color='#999999' style="pointer-events: auto;" />


                    <van-button icon="arrow" color='#73BEC9' type="primary" bindtap="on_course" />


                </view>

            </view>

        </block>


        <!-- HACK: animation设置为false,避免开始显示此组件的滑动效果 -->

        <movable-view hidden="{{ !dragElement }}" class="index_view_mo " style='height: {{ elementHeight }}px;' direction="vertical" disabled animation="{{ false }}" y="{{ movableViewY }}">

            <view class="index_view_p_mo">

                <text>{{ dragElement.bj_title }}</text>

                <text>当前进度:{{ dragElement.jidnu }}</text>

                <text>{{ dragElement.zhouqi }}</text>

                <text>{{ dragElement.renshu }}名学员</text>

            </view>

            <!-- <van-button icon="arrow" color='#73BEC9' type="primary" /> -->

        </movable-view>

    </movable-area>



    /* pages/index/index.wxss */

    .van-field__control {

        background-color: #fff;

    }


    .column_view_index {

        display: flex;

        flex-direction: column;

        justify-content: space-between;

        height: 200rpx;

    }


    .index_head {

        display: flex;

        justify-content: space-between;

        align-items: center;

        margin: 20rpx 0;

    }


    .index_view {

        background-color: #9999990f;

        margin: 20rpx 0;

        display: flex;

        justify-content: space-between;

        align-items: center;

        padding: 30rpx;


    }


    .index_view_p {

        display: flex;

        flex-direction: column;

        line-height: 60rpx;

    }


    .index_view_mo {

        background-color: #73BEC9a6;

        display: flex;

        justify-content: space-between;

        align-items: center;

        width: 90%;

        padding: 30rpx;


    }


    .index_view_p_mo {

        display: flex;

        flex-direction: column;

        line-height: 60rpx;

        color: #fff;

    }


    .flex-center {

        display: flex;

        align-items: center;

        justify-content: center;

    }


    .movable-container {

        width: 100%;

    }



    .item--tran {

        background-color: #9999990f;

    }


    .item--target {

        background-color: #73BEC9;


    }


    .view_events {

        pointer-events: auto;

    }

    .view_events_none {

        pointer-events: none;

    }


    .area_events {

        pointer-events: none;

    }


    .area_events_auto {

        pointer-events: auto;

    }



// pages/index/index.js

Page({


  /**

   * 页面的初始数据

   */

  data: {

    // 排序状态码

    movale_ok: 1,

    value: '',

    //#region 纯数据字段

    /** 屏幕高度,单位px */

    _windowHeight: null,

    /** 开始触摸时的单一项左上角y坐标 */

    _startOffsetY: null,

    /** 开始触摸位置y坐标 */

    _startPageY: null,

    /** 开始触摸项索引 */

    _startDragElementIndex: null,


    /** 滑动偏移 */

    _scrollThreshold: 0.5,


    /** 距顶部/左边多远时,触发 _scrollToUpper 事件,单位px,即上滑至屏幕顶部 */

    _upperThreshold: 100,

    /** 距底部/右边多远时,触发 _scrollToLower 事件,单位px,即下滑至屏幕底部 */

    _lowerThreshold: 100,

    /** 上滑和下滑时间,单位毫秒 */

    _scrollDuration: 1000,

    //#endregion


    /** 列表 */

    list: [{

      id: 1,

      content: 1,

      bj_title: '21级秋季 - 本科定制班 - 1班',

      jidnu: '第10章 第10节',

      zhouqi: '2022.06-2023.10',

      renshu: '60'

    }, {

      id: 2,

      content: 2,

      bj_title: '21级秋季 - 本科定制班 - 2班',

      jidnu: '第10章 第10节',

      zhouqi: '2022.06-2023.10',

      renshu: '60'

    }, {

      id: 3,

      content: 3,

      bj_title: '21级秋季 - 本科定制班 - 3班',

      jidnu: '第10章 第10节',

      zhouqi: '2022.06-2023.10',

      renshu: '60'

    }, {

      id: 3,

      content: 3,

      bj_title: '21级秋季 - 本科定制班 - 3班',

      jidnu: '第10章 第10节',

      zhouqi: '2022.06-2023.10',

      renshu: '60'

    }, {

      id: 3,

      content: 3,

      bj_title: '21级秋季 - 本科定制班 - 3班',

      jidnu: '第10章 第10节',

      zhouqi: '2022.06-2023.10',

      renshu: '60'

    }, {

      id: 4,

      content: 4,

      bj_title: '21级秋季 - 本科定制班 - 4班',

      jidnu: '第10章 第10节',

      zhouqi: '2022.06-2023.10',

      renshu: '60'

    }],


    /** 单一项高度 */

    elementHeight: 120,


    /** 滑动项 */

    dragElement: null,

    /** movable-view组件y轴坐标,滑动时滑动项左上角距离文档顶部纵坐标,单位px */

    movableViewY: null,

    /** 滑动过程中经过的项 */

    lastTarget: null,

  },

  onLoad: function (options) {},

  on_course: function () {

    wx.navigateTo({

      url: '/pages/course/course',

    })

  },

  on_student: function () {

    wx.navigateTo({

      url: '/pages/student/student',

    })

  },

  /** 生命周期函数--监听页面展示 */

  onShow() {

    this._getWindowHeight();

  },

  /** 长按触发事件 */

  onLongPress(event) {


    let dragElementIndex = event.currentTarget.dataset.index;

    let dragElement = this.data.list[dragElementIndex];

    let movale_ok = this.data.movale_ok

    this.setData({

      /** 点击项左上角y坐标 */

      _startOffsetY: event.target.offsetTop,

      /** 点击位置y坐标 */

      _startPageY: event.touches[0].pageY,

      /** 点击项索引 */

      _startDragElementIndex: dragElementIndex,

      /** 点击项 */

      dragElement,

      /** movable-view组件左上角y坐标 */

      movableViewY: event.target.offsetTop,

      movale_ok: 0

    });

    console.log(movale_ok);



  },

  onPaixu() {

    let movale_ok = this.data.movale_ok

    this.setData({

      movale_ok: 0

    });

  },

  /**

   * 手指触摸后移动

   * - 触底或触顶时下滑或者上滑

   * - 移动movable-view

   */

  onTouchMove(event) {

    // console.log('[onTouchMove]', event);


    // 长按事件

    if (this.data.dragElement) {

      let clientY = event.touches[0].clientY; // 触摸点位置在显示屏幕区域左上角Y坐标

      this._pageScroll(clientY);


      /** 触摸点位置距离文档左上角Y坐标 */

      let pageY = event.touches[0].pageY;

      /** 和最初点击位置比较移动距离 */

      let targetMoveDistance = pageY - this.data._startPageY;

      /** 移动后的movable-view组件位置 */

      let movableViewY = this.data._startOffsetY + targetMoveDistance;

      /** 经过项索引 */

      let targetIndex = this._computeFutureIndex(targetMoveDistance, this.data._startDragElementIndex);


      this.setData({

        movableViewY,

        lastTarget: targetIndex

      });


    }

  },

  /** 滑动结束 */

  onTouchEnd(event) {

    // console.log('[onTouchEnd]', event);


    if (this.data.dragElement) {

      let list = this._deepCopy(this.data.list);

      /** 结束点位置y坐标 */

      let pageY = event.changedTouches[0].pageY;

      /** 和初始点击位置比较移动距离 */

      let targetMoveDistance = pageY - this.data._startPageY;

      /** 初始点击项索引 */

      let dragElementIndex = this.data._startDragElementIndex;


      /** 目标项索引 */

      const futureIndex = this._computeFutureIndex(targetMoveDistance, dragElementIndex);

      if (futureIndex !== false) {

        list.splice(futureIndex, 0, list.splice(dragElementIndex, 1)[0]); // 移动位置

      }

      var movale_ok = this.data.movale_ok

      this.setData({

        list,

        dragElement: null,

        lastTarget: null,

        movale_ok: 1

      });

      console.log(movale_ok);


    }


  },

  /** 阻止滑动 */

  onHackTouchMove() {},

  /** 获取可使用窗口高度,单位px */

  _getWindowHeight() {

    try {

      const {

        windowHeight

      } = wx.getSystemInfoSync();

      this.setData({

        _windowHeight: windowHeight

      });

    } catch (err) {

      console.error('[_getWindowHeight]', err);

    }

  },

  /** 页面滑动 */

  _pageScroll(clientY) {

    if (clientY + this.data._upperThreshold >= this.data._windowHeight) {

      // 下滑接近屏幕底部

      wx.pageScrollTo({

        scrollTop: clientY + this.data.elementHeight,

        duration: this.data._scrollDuration

      });

    } else if (clientY - this.data._lowerThreshold <= 0) {

      // 上滑接近屏幕顶部

      wx.pageScrollTo({

        scrollTop: clientY - this.data.elementHeight,

        duration: this.data._scrollDuration

      })

    }

  },

  /**

   * 计算目标索引

   * @param {number} targetMoveDistance 移动距离

   * @param {number} dtagElementIndex 初始移动项索引

   * 若轻轻拂动则返回false

   */

  _computeFutureIndex(targetMoveDistance, dragElementIndex) {

    let willInsertAfter = this._getSwapDirection(targetMoveDistance);

    if (willInsertAfter !== false) {

      /** 偏移索引 */

      let offsetElementIndex = dragElementIndex + willInsertAfter;

      /** 移动步数 */

      let step = targetMoveDistance / this.data.elementHeight;

      /** 步数补偿,当只有移动距离超过单项 _scrollThreshold 时才算有效 */

      if (step <= -1) {

        step += this.data._scrollThreshold;

      } else if (step >= 1) {

        step -= this.data._scrollThreshold;

      }

      /** 目标索引 */

      let futureIndex = parseInt(step) + offsetElementIndex;


      // 避免越界

      if (futureIndex < 0) {

        futureIndex = 0;

      } else if (futureIndex > this.data.list.length - 1) {

        futureIndex = this.data.list.length - 1;

      }


      return futureIndex;

    } else {

      return willInsertAfter;

    }

  },

  /**

   * 获取滑动方向

   * @param {number} targetMoveDistance 移动距离

   * @returns {number/boolean}

   *  - 1 下滑

   *  - -1 上滑

   *  - false 拂动,滑动距离小于一半单项高度

   */

  _getSwapDirection(targetMoveDistance) {

    if (Math.abs(targetMoveDistance) < this.data.elementHeight / 2) {

      // 轻轻拂动,滑动距离小于1/2单项高度

      return false;

    } else if (targetMoveDistance >= this.data.elementHeight / 2) {

      return 1; // 下滑

    } else if (targetMoveDistance <= this.data.elementHeight / -2) {

      return -1; // 上滑

    }

  },

  /** 深拷贝 */

  _deepCopy(obj) {

    // 只拷贝对象

    if (typeof obj !== 'object') return;

    // 根据obj的类型判断是新建一个数组还是一个对象

    var newObj = obj instanceof Array ? [] : {};

    for (var key in obj) {

      // 遍历obj,并且判断是obj的属性才拷贝

      if (obj.hasOwnProperty(key)) {

        // 判断属性值的类型,如果是对象递归调用深拷贝

        newObj[key] = typeof obj[key] === 'object' ? this._deepCopy(obj[key]) : obj[key];

      }

    }

    return newObj;

  }

})


    文章版权及转载声明

    作者:jstang本文地址:https://www.jstang.cn/post/11.html发布于2022-07-26
    文章转载或复制请以超链接形式并注明出处jstang博客

    • 上一篇 :微信小程序文字超出自动换行
    • 下一篇 :微信小程序元素自动换行

    同类推荐

    发表评论

    留言:dddxzxx

    最新文章

    windows定时访问脚本bat

    windows定时访问脚本bat

    @echo off:loopREM 获取当前小时(24小时制...

    • 42
    • 0
    宝塔瘦身,清理硬盘

    宝塔瘦身,清理硬盘

    1  /var/log/journal/...

    • 130
    • 0
    世界知识现在掌握在每个人的手掌中

    世界知识现在掌握在每个人的手掌中

    世界知识现在掌握在每个人的手掌中...

    • 216
    • 0
    想法--执行

    想法--执行

    未来属于那些有想法、还能动手去做的人。创办一家公司并不真的需...

    • 229
    • 0
    老张站群-单程序N域名站群插件演示

    老张站群-单程序N域名站群插件演示

    操作演示视频部分https://www.bilibili.c...

    • 724
    • 0

    热门排行

    css实现超出固定长度的部分以省略号显示

    css实现超出固定长度的部分以省略号显示

    1.一行中超出固定长度的部分以省略号显示#div1{&n...

    • 40441
    • 1
    老张站群-站群教程

    老张站群-站群教程

    注意 进行 超时设置 以防止50x PS : 源站...

    • 2671
    • 0
    python线程池

    python线程池

    ...

    • 2364
    • 0
    微信小程序对象赋值

    微信小程序对象赋值

    data{valueDa:{}}this.set...

    • 2341
    • 0
    小说正在扼杀我的阅读思考能力....

    小说正在扼杀我的阅读思考能力....

    从18岁就开始看第一本小说《诛仙》,慢慢的看到了现在28岁。...

    • 2337
    • 0

    猜你喜欢

    专治拖延“懒”的自测有效办法

    专治拖延“懒”的自测有效办法

    无意中看到一个帖子,大概意思讲的是计划做A事,但是 因为各种...

    • 1765
    • 1
    脑袋里的想法过多的时候,需要分清“这”对自己是什么

    脑袋里的想法过多的时候,需要分清“这”对自己是什么

    需要分清楚想做的事情 对自己的 到底 有没有用帮助。...

    • 1170
    • 0
    dede织梦接口发布后自动更新首页栏目页

    dede织梦接口发布后自动更新首页栏目页

    ...

    • 1316
    • 0
    严禁“嘚瑟”!!!

    严禁“嘚瑟”!!!

    自己只是收获一时快感但能让你产生“嘚瑟”“炫耀”的点已经就会...

    • 1618
    • 0
    css 固定宽高后图片裁剪

    css 固定宽高后图片裁剪

    object-fit: cover;...

    • 1196
    • 0

    标签

    • zblog插件
    • thinkphp
    • 企业微信
    • 标签2
    • 微信公众号
    • pbootcms迁移
    • 老张站群
    • 标签3
    • 明天的天气
    • องค์ประกอบของนักเรียนชั้นประถมศึกษา
    嘿,欢迎咨询
    jstang博客
    回到顶部

    涉及到的所有程序逻辑仅用来学习交流,严禁用于非法用途,产生的一切后果自行承担! 。用户在使用程序时,应遵守相关法律法规,不得利用本软件进行任何违法活动 ,因用户违反本《协议》或使用程序造成的任何损失和法律责任,由用户自行承担,本程序不承担 任何责任。冀ICP备2022024290号-1