WXML部分

1 <view class="index">
2
3 <!-- 数据展示区 -->
4 <scroll-view
5 class="scroll-list"
6 scroll-y
7 style="height: {{windowHeight - bottomHeight}}px"
8 bindscroll="bindscroll">
9 <view class="scroll-item" wx:for="{{optionsList}}" wx:key="index">
10 <view>{{item.time}}</view>
11 </view>
12 </scroll-view>
13
14 <!-- 页面可拖拽区域 -->
15 <view
16 wx:if='{{editting}}'
17 class="touchView"
18 catchtouchstart="scrollTouchStart"
19 catchtouchmove="scrollTouchMove"
20 catchtouchend="scrollTouchEnd"
21 style="height: {{windowHeight - bottomHeight}}px">
22 </view>
23
24 <!-- 页面拖拽处理区域 -->
25 <movable-area
26 wx:if='{{editting}}'
27 class="moveable_row"
28 style="height: {{windowHeight - bottomHeight}}px">
29 <movable-view
30 class="moveable_item {{moveData ? 'show' : 'hide'}}"
31 style="height: {{scrollItemHeight}}px;"
32 direction="vertical"
33 x="{{moveData.x}}"
34 y="{{moveData.y}}"
35 inertia="false"
36 damping="9999"
37 friction="9999"
38 >
39 <view class="scroll-item moving" hidden='{{!moveData}}'>
40 <view>{{selectItem.time}}</view>
41 </view>
42 </movable-view>
43 </movable-area>
44
45 <!-- 底部栏 -->
46 <view class="index-bottom">
47 <button type="primary" wx:if='{{!editting}}' bindtap="changeEditing">编辑</button>
48 <button type="warn" wx:else bindtap="changeEditing">取消</button>
49 </view>
50
51 </view>
WXSS部分

1 .index {
2 position: relative;
3 }
4
5 /* 数据展示区 */
6 .scroll-list{
7 width: 100%;
8 }
9 .scroll-item {
10 width: 100%;
11 padding: 10rpx 20rpx;
12 box-sizing: border-box;
13 border: 1px solid #999;
14 }
15 .scroll-item.moving {
16 border: 1px dashed blue;
17 }
18
19 /* 页面可拖拽区域 */
20 .touchView {
21 width: 100%;
22 position: absolute;
23 left: 0;
24 top: 0;
25 z-index: 1;
26 }
27
28 /* 页面拖拽处理区域 */
29 .moveable_row {
30 width: 100%;
31 position: absolute;
32 left: 0;
33 top: 0;
34 }
35 .moveable_item {
36 width: 100%;
37 }
38 .moveable_item.show {
39 background: #fff;
40 }
41 .moveable_item.hide {
42 background: transparent;
43 }
44
45
46 /* 底部栏 */
47 .index-bottom {
48 width: 100%;
49 display: flex;
50 justify-content: flex-end;
51 padding: 10rpx 20rpx;
52 box-sizing: border-box;
53 }
js部分  

1 Page({
2 data:{
3 optionsList: [], // 数据源
4 windowHeight: 0, // 屏幕高度
5 scrollItemHeight: 0, // 列表单项高度
6 bottomHeight: 0, // 底部按钮高度
7 selectItem: {}, // 当前选中元素
8 selectIndex: 0, // 当前选中索引
9 editting: true, // 是否是“编辑”状态
10 moveData: null, // 列表项移动时记录移动位置
11 scrollTop: 0 // scroll-view距离顶部距离
12 },
13 // 初始化页面数据
14 init() {
15 this.setData({
16 optionsList: [{time: '12:00'}, {time: '13:00'}, {time: '14:00'}, {time: '15:00'}, {time: '16:00'}, {time: '17:00'}, {time: '18:00'}, {time: '19:00'}, {time: '20:00'}, {time: '21:00'}, {time: '22:00'}, {time: '23:00'}, {time: '24:00'}, {time: '25:00'}, {time: '26:00'}, {time: '27:00'}, {time: '28:00'}, {time: '29:00'}, {time: '30:00'}, {time: '31:00'}, {time: '32:00'}, {time: '33:00'}, {time: '34:00'}, {time: '35:00'}],
17 windowHeight: wx.getSystemInfoSync().windowHeight
18 }, () => {
19 wx.createSelectorQuery().select('.index-bottom').boundingClientRect(res => {
20 this.setData({
21 bottomHeight: res.height
22 })
23 }).exec()
24 wx.createSelectorQuery().select('.scroll-item').boundingClientRect(res => {
25 this.setData({
26 scrollItemHeight: res.height
27 })
28 }).exec()
29 });
30 },
31
32 // 开始拖拽
33 scrollTouchStart(event) {
34 const { scrollItemHeight } = this.data
35 const firstTouchPosition = {
36 x: event.changedTouches[0].pageX,
37 y: event.changedTouches[0].pageY,
38 }
39 const { data, index } = this.getPositionDomByXY(firstTouchPosition);
40 this.setData({
41 moveData:{
42 x: 0,
43 y: firstTouchPosition.y - scrollItemHeight / 2
44 },
45 selectItem: data,
46 selectIndex: index
47 })
48
49 },
50
51 // 拖拽ing...
52 scrollTouchMove(event) {
53 const { scrollItemHeight } = this.data
54 this.setData({
55 moveData:{
56 x: 0,
57 y: event.changedTouches[0].pageY - scrollItemHeight / 2
58 },
59 })
60
61 },
62
63 // 拖拽结束
64 scrollTouchEnd:function (event) {
65 const { selectIndex, optionsList } = this.data
66 const endTouchPosition = {
67 x: event.changedTouches[0].pageX,
68 y: event.changedTouches[0].pageY,
69 }
70 const { index } = this.getPositionDomByXY(endTouchPosition)
71 // 交换顺序
72 const temp = optionsList[selectIndex]
73 optionsList[selectIndex] = optionsList[index]
74 optionsList[index] = temp
75 this.setData({
76 optionsList,
77 moveData: null
78 })
79 },
80
81 // 根据(x,y)坐标轴获取页面元素
82 getPositionDomByXY(potions) {
83 const { scrollItemHeight, optionsList, scrollTop } = this.data
84 const y = potions.y + scrollTop;
85 const len = optionsList.length
86 for(let i = 0; i < len; i++){
87 if(y >= i*scrollItemHeight && y < (i+1)*scrollItemHeight){
88 // 返回匹配到的数据项
89 return {
90 data: optionsList[i],
91 index: i
92 };
93 }
94 }
95 return y > (len-1)*scrollItemHeight ? {
96 // 匹配项位于列表之下
97 data: optionsList[len - 1],
98 index: len - 1
99 } : {
100 // 匹配项位于列表之上
101 data: optionsList[0],
102 index: 0
103 }
104 },
105
106 // 切换编辑状态
107 changeEditing() {
108 const { editting } = this.data
109 this.setData({ editting: !editting })
110 },
111
112 // 监听滚动事件
113 bindscroll(e) {
114 this.data.scrollTop = e.detail.scrollTop
115 },
116 onLoad: function () {
117 this.init()
118 },
119 });

微信小程序拖动列表功能的更多相关文章

  1. 微信小程序新闻列表功能(读取文件、template模板使用)

    微信小程序新闻列表功能(读取文件.template) 不忘初心,方得始终.初心易得,始终难守. 在之前的项目基础上进行修改,实现读取文件内容作为新闻内容进行展示. 首先,修改 post.wxml 文件 ...

  2. 微信小程序调用蓝牙功能控制车位锁

    第一次学用微信小程序,项目需要,被逼着研究了一下,功能是调用微信小程序的蓝牙功能,连接上智能车位锁,控制升降,大概步骤及调用的小程序接口API如下: 1.打开蓝牙模块 wx.openBluetooth ...

  3. 微信小程序实战 购物车功能

    代码地址如下:http://www.demodashi.com/demo/12400.html 一.准备工作 软件环境:微信开发者工具 官方下载地址:https://mp.weixin.qq.com/ ...

  4. 微信小程序在线支付功能使用总结

    最近需要在微信小程序中用到在线支付功能,于是看了一下官方的文档,发现要在小程序里实现微信支付还是很方便的,如果你以前开发过服务号下的微信支付,那么你会发现其实小程序里的微信支付和服务号里的开发过程如出 ...

  5. 微信小程序开发-蓝牙功能开发

    0. 前言 这两天刚好了解了一下微信小程序的蓝牙功能.主要用于配网功能.发现微信的小程序蓝牙API已经封装的很好了.编程起来很方便.什么蓝牙知识都不懂的情况下,不到两天就晚上数据的收发了,剩下的就是数 ...

  6. 微信小程序之购物车功能

    前言 以往的购物车,基本都是通过大量的 DOM 操作来实现.微信小程序其实跟 vue.js 的用法非常像,接下来就看看小程序可以怎样实现购物车功能. 需求 先来弄清楚购物车的需求. 单选.全选和取消, ...

  7. [转]微信小程序之购物车功能

    本文转自:https://www.cnblogs.com/linxin/p/6834206.html 前言 以往的购物车,基本都是通过大量的 DOM 操作来实现.微信小程序其实跟 vue.js 的用法 ...

  8. 【微信小程序】转载:微信小程序之购物车功能

    前言 以往的购物车,基本都是通过大量的 DOM 操作来实现.微信小程序其实跟 vue.js 的用法非常像,接下来就看看小程序可以怎样实现购物车功能. 需求 先来弄清楚购物车的需求. 单选.全选和取消, ...

  9. 运用wxs制作微信小程序左滑功能和跳转,性能更优越

    锲子 微信小程序自定义左滑功能加上跳转,换成以往,左滑功能的逻辑一般是在js中实现,但在拖动方面,性能并不是那么的流畅.如今,官方新扩展了一套脚本语言wxs,在IOS设备上运行,性能会比JS快2~20 ...

随机推荐

  1. Log4j2详解——XML配置详解

    Log4j2详解--XML配置详解 找到了个很详细的文章链接 https://www.jianshu.com/p/bfc182ee33db

  2. tp5 webupload文件上传至七牛云

    1:composer安装: composer require qiniu/php-sdk 2: 配置使用: 在tp5.1的配置文件app.php中配置七牛云的参数 'qiniu' => [ 'a ...

  3. MySQL-DB-封装-简易版

    <?php class DB{ private $link; public function __construct($host,$user,$password,$dbname,$port) { ...

  4. CF1515H口胡

    居然一下就做出来了...不知道是不是对的/fad 考虑操作的本质,首先将所有元素插入线段树中. 来依次考虑每一种操作: 区间与 注意到这个操作类似将某些节点的右儿子合并到左儿子上,而一个节点最多被合并 ...

  5. Qt记事本,美化版

    主体代码实现 #include "mainwindow.h" #include "ui_mainwindow.h" #include<QMenu> ...

  6. SqlServer Split 的实现

    数据库如何处理传参用指定字符隔开参数的情况 如"name1,name3,name5" 共2种方式, 1.数据库内置函数STRING_SPLIT(sql2016之前的版本不支持该函数 ...

  7. 绕过CDN找到⽬标站点真实IP

    一.判断目标网站是否使用CDN 在渗透测试中,如果连真实 IP 都没有找到的话,相当于连门都没有找到.所以,如何验证目标网站是否使用了 CDN 呢? 1.多地 ping 法(一般情况下使用多地 pin ...

  8. bzoj4241/AT1219 历史研究(回滚莫队)

    bzoj4241/AT1219 历史研究(回滚莫队) bzoj它爆炸了. luogu 题解时间 我怎么又在做水题. 就是区间带乘数权众数. 经典回滚莫队,一般对于延长区间简单而缩短区间难的莫队题可以考 ...

  9. Nginx HTTP负载均衡和反向代理的配置与优化

    一.什么是负载均衡和反向代理 1.负载均衡 负载均衡是由多台服务器以对称的方式组成一个服务器集合,每台服务器具有等价的地位,都可以单独提供服务而无需其他服务的辅助.通过某种负载分担技术,将外部发送来的 ...

  10. Java 中的同步集合与并发集合有什么区别?

    同步集合与并发集合都为多线程和并发提供了合适的线程安全的集合,不过并发 集合的可扩展性更高.在 Java1.5 之前程序员们只有同步集合来用且在多线程并发 的时候会导致争用,阻碍了系统的扩展性.Jav ...