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. SpringCloudStream(RabbitMQ&Kafka)&Spring-Kafka配置使用

    目录 是什么 解决问题 使用方式 创建生产者项目 pom yml 生产消息方法 接口 实现 创建消费者项目 pom yml 接收消息方法 重复消费 消费者yml 持久化 消费者负载个性配置(预拉取) ...

  2. ASP.NET Core 6框架揭秘实例演示[24]:中间件的多种定义方式

    ASP.NET Core的请求处理管道由一个服务器和一组中间件组成,位于 "龙头" 的服务器负责请求的监听.接收.分发和最终的响应,针对请求的处理由后续的中间件来完成.中间件最终体 ...

  3. hive 操作

    show databases ;use default;show tables ;create table student(id int, name string) ROW FORMAT DELIMI ...

  4. MySQL between and 边界测试

    看到有一些博客说 between and 有不含边界的情况,于是测试了一把,记录如下.先说结论:between and 不存在不含边界的情况 1. between and 是包含边界的 id betw ...

  5. 查找goog13的ip

    C:\Users\Deen>ping 172.217.24.14 Pinging 172.217.24.14 with 32 bytes of data: Reply from 172.217. ...

  6. 配置Openfiler做ISCS实验

    在VMware workstation中安装openfiler(linux底层)   系统安装 选择redhat6,64bit   分配30G 2.   3.. 4.5.               ...

  7. 配置Django环境后,运行时报错

    (背景)安装完Django,并配置完成. 在setting.py中设置了数据库时,出现的报错. 点击查看 数据库配置 DATABASES = { 'default': { # 'ENGINE': 'd ...

  8. C++ 并发编程1

    一个简单的并发编程的举例 #include <iostream> #include <thread> using namespace std; void hello(){ co ...

  9. Linux 下命令有哪几种可使用的通配符?分别代表什么含义?

    "?"可替代单个字符. "*"可替代任意多个字符. 方括号"[charset]"可替代 charset 集中的任何单个字符,如[a-z],[ ...

  10. 什么是 ThreadLocal 变量?

    ThreadLocal 是 Java 里一种特殊的变量.每个线程都有一个 ThreadLocal 就是每 个线程都拥有了自己独立的一个变量,竞争条件被彻底消除了.它是为创建代价 高昂的对象获取线程安全 ...