之前在网上搜索拖拽列表的实现时,发现了有好多的方法都是基于像素位置的计算实现的,这种方法要求列表元素的大小以及列表的位置有着非常严格的要求,修改和拓展起来非常的麻烦。于是我自己动手实现了一个基于页面元素定位的实现,这种方法只需要每行的高度,拓展和应用到自己的小程序里非常的简单。

 
实现效果

JS

Page({

  /**
* 页面的初始数据
*/
data: {
optionList: [], movableViewInfo: {
y: 0,
showClass: 'none',
data: {}
}, pageInfo: {
rowHeight: 47,
scrollHeight: 85, startIndex: null,
scrollY: true,
readyPlaceIndex: null,
startY: 0,
selectedIndex: null,
}
}, dragStart: function (event) {
var startIndex = event.target.dataset.index
console.log('获取到的元素为', this.data.optionList[startIndex])
// 初始化页面数据
var pageInfo = this.data.pageInfo
pageInfo.startY = event.touches[0].clientY
pageInfo.readyPlaceIndex = startIndex
pageInfo.selectedIndex = startIndex
pageInfo.scrollY = false
pageInfo.startIndex = startIndex this.setData({
'movableViewInfo.y': pageInfo.startY - (pageInfo.rowHeight / 2)
})
// 初始化拖动控件数据
var movableViewInfo = this.data.movableViewInfo
movableViewInfo.data = this.data.optionList[startIndex]
movableViewInfo.showClass = "inline" this.setData({
movableViewInfo: movableViewInfo,
pageInfo: pageInfo
})
}, dragMove: function (event) {
var optionList = this.data.optionList
var pageInfo = this.data.pageInfo
// 计算拖拽距离
var movableViewInfo = this.data.movableViewInfo
var movedDistance = event.touches[0].clientY - pageInfo.startY
movableViewInfo.y = pageInfo.startY - (pageInfo.rowHeight / 2) + movedDistance
console.log('移动的距离为', movedDistance) // 修改预计放置位置
var movedIndex = parseInt(movedDistance / pageInfo.rowHeight)
var readyPlaceIndex = pageInfo.startIndex + movedIndex
if (readyPlaceIndex < 0 ) {
readyPlaceIndex = 0
}
else if (readyPlaceIndex >= optionList.length){
readyPlaceIndex = optionList.length - 1
} if (readyPlaceIndex != pageInfo.selectedIndex ) {
var selectedData = optionList[pageInfo.selectedIndex] optionList.splice(pageInfo.selectedIndex, 1)
optionList.splice(readyPlaceIndex, 0, selectedData)
pageInfo.selectedIndex = readyPlaceIndex
}
// 移动movableView
pageInfo.readyPlaceIndex = readyPlaceIndex
// console.log('移动到了索引', readyPlaceIndex, '选项为', optionList[readyPlaceIndex]) this.setData({
movableViewInfo: movableViewInfo,
optionList: optionList,
pageInfo: pageInfo
})
}, dragEnd: function (event) {
// 重置页面数据
var pageInfo = this.data.pageInfo
pageInfo.readyPlaceIndex = null
pageInfo.startY = null
pageInfo.selectedIndex = null
pageInfo.startIndex = null
pageInfo.scrollY = true
// 隐藏movableView
var movableViewInfo = this.data.movableViewInfo
movableViewInfo.showClass = 'none' this.setData({
pageInfo: pageInfo,
movableViewInfo: movableViewInfo
})
}, /**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
var optionList = [
"段落1 内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容",
"段落2 内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容",
"段落3 内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容",
"段落4 内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容",
"段落5 内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容",
"段落6 内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容",
"段落7 内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容",
"段落8 内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容",
"段落9 内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容"
] this.setData({
optionList: optionList
})
}, })

WXML

<view class='zhuti'>
<view class='row title-row' style='height: {{pageInfo.rowHeight}}px;'>
<view class="col1">信息</view>
<view class="col2">详情</view>
<view class="col3">排序</view>
</view> <movable-area class='movable-area'
style='display:{{movableViewInfo.showClass}}; height:{{pageInfo.scrollHeight}}%;'>
<movable-view class='row list-row movable-row'
out-of-bounds='true'
damping='999'
style='height:{{pageInfo.rowHeight}}px;'
direction="vertical"
y="{{movableViewInfo.y}}">
<view class='col1 content' >{{movableViewInfo.data}}</view>
<view class="col2" >
<icon type='info' color='Gray' size='22' />
</view>
<view class="col3" >
<icon type='download' color='Gray' size='25' />
</view>
</movable-view>
</movable-area> <scroll-view scroll-y='{{pageInfo.scrollY}}' style='height: {{pageInfo.scrollHeight}}%'>
<block wx:for='{{optionList}}'>
<view class='row list-row {{pageInfo.readyPlaceIndex == index ? "ready-place" : ""}}' style='height: {{pageInfo.rowHeight}}px;'>
<view class='col1 content' >{{item}}</view>
<view class="col2" >
<icon type='info' color='Gray' size='22'
data-index='{{index}}'
bindtap='showDetail'
/>
</view>
<view class="col3" >
<icon type='download' color='Gray' size='25'
data-index='{{index}}'
bindtouchstart='dragStart'
bindtouchmove='dragMove'
bindtouchend='dragEnd'
/>
</view>
</view>
</block>
</scroll-view>
</view>

WXSS

page {
height: 100%;
width: 100%;
} .zhuti {
height: 100%;
width: 100%; position: relative;
} .row {
height: 47px;
width: 100%; display: flex;
justify-content: space-around;
align-items: center;
} .title-row {
border-bottom: 1px solid #888888; color: #888888;
} .list-row {
padding: 8px 0px;
border-bottom: 1px solid #D9D9D9;
background-color: white;
} .movable-area {
position: absolute;
top: 0;
left: 0;
z-index: 10;
width: 100%;
} .movable-row {
box-shadow: #D9D9D9 0px 0px 20px;
} .col1 {
width: 60%;
}
.col2 {
width: 10%;
}
.col3 {
width: 10%;
} .ready-place {
background-color: #CCCCCC
} .content {
font-size: 17px; white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}

 

作者:HoPGoldy
链接:https://www.jianshu.com/p/d965c80fe901
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

实现拖拽列表-微信小程序的更多相关文章

  1. 使用movable-view制作可拖拽的微信小程序弹出层效果。

    仿了潮汐睡眠小程序的代码.[如果有侵权联系删除 最近做的项目有个弹出层效果,类似音乐播放器那种.按照普通的做了一般感觉交互不是很优雅,设计妹子把潮汐睡眠的弹层给我看了看,感觉做的挺好,于是乘着有空仿照 ...

  2. 微信小程序导航:官方工具+精品教程+DEMO集合(1月7更新)

    1:官方工具:https://mp.weixin.qq.com/debug/w ... tml?t=14764346784612:简易教程:https://mp.weixin.qq.com/debug ...

  3. 微信小程序教程汇总

    目前市面上在内测期间出来的一些实战类教程还是很不错的,主要还是去快速学习小程序开发的整体流程,一个组件一个组件的讲的很可能微信小程序一升级,这个组件就变了,事实本就如此,谁让现在是内测呢.我们不怕,下 ...

  4. 微信小程序 教程及示例

    作者:初雪链接:https://www.zhihu.com/question/50907897/answer/128494332来源:知乎著作权归作者所有,转载请联系作者获得授权.微信小程序正式公测, ...

  5. 微信小程序资料集合

    一:官方地址集合: 1:官方工具:https://mp.weixin.qq.com/debug/wxadoc/dev/devtools/download.html?t=1476434678461 2: ...

  6. 近期热门微信小程序demo源码下载汇总

    近期微信小程序demo源码下载汇总,乃小程序学习分析必备素材!点击标题即可下载: 即速应用首发!原创!电商商场Demo 优质微信小程序推荐 -秀人美女图 图片下载.滑动翻页 微信小程序 - 新词 GE ...

  7. 微信小程序踩坑集合

    1:官方工具:https://mp.weixin.qq.com/debug/w ... tml?t=1476434678461 2:简易教程:https://mp.weixin.qq.com/debu ...

  8. 微信小程序开发学习资料

    作者:初雪链接:https://www.zhihu.com/question/50907897/answer/128494332来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明 ...

  9. 微信小程序 -- 基于 movable-view 实现拖拽排序

    微信小程序 -- 基于 movable-view 实现拖拽排序 项目基于colorui样式组件 ColorUI组件库 (color-ui.com) 1.实现效果 2. 设计思路 movable-vie ...

随机推荐

  1. spring boot 2.2.0开始freemarker模板默认扩展名改为ftlh了

    2.2.0这个版本刚发布的时候更新到了这个版本,然后使用freemarker 的webapp运行报错. 查了spring boot的changelog,搜freemarker查到了这条.ftlh,使f ...

  2. SA详细注释不压行代码

    ){ //变量含义:m是字符集大小,n是字符串长度,c是一个桶数组,a[i]是字符串(下标从1开始) //rk[i]就是suffix(i)的字典序排名,sa[i]就是要求的排名为i的后缀的起始位置,即 ...

  3. 模块引用方式利弊辨析: 全局绝对引用(alias) && 长相对引用

    前言 这个问题首先要从我们项目的require语句开始说起. 当打开我们项目的时候,我们可能会看到一大堆长相对引用,如下所示: import component from '../../../../c ...

  4. 前端小白webpack学习(一)

    俗话说得好,好记性不如烂笔头. 之前就在学习中看过webpack的教程,然而一段时间没用,火速的忘光了.写这篇博文,做个总结,也让自己以后有个地方回顾. 看webpack之前,我先去看了一下官方文档, ...

  5. SpringCloud之Eureka:服务发布与调用例子

    Eureka是Netflix开发的服务发现框架,本身是一个基于REST的服务,主要用于定位运行在AWS域中的中间层服务,以达到负载均衡和中间层服务故障转移的目的. SpringCloud将它集成在其子 ...

  6. 一文解读HTTP2 (转)

    作为一个经常和web打交道的程序员,了解这些协议是必须的,本文就向大家介绍一下这些协议的区别和基本概念,文中可能不局限于前端知识,还包括一些运维,协议方面的知识,希望能给读者带来一些收获,如有不对之处 ...

  7. 转战物联网·基础篇07-深入理解MQTT协议之控制报文(数据包)格式

      在MQTT协议中,一个控制报文(数据包)的结构按照前后顺序分如下三部分: 结构名 中文名 解释说明 Fixed header 固定报头 报文的最开始部分,所有报文都包含这个部分 Variable ...

  8. 在Ubuntu上安装Miniconda

    在Ubuntu上安装Miniconda Anaconda是一个开源的Python包管理器,而Miniconda则是轻量级的Anaconda 下载地址:https://docs.conda.io/en/ ...

  9. 循环语句for基本概述

    循环语句for基本概述 01. for循环基础语法 for 变量名 in [ 取值列表 ]do 循环体done 02. for循环基本使用示例 #取值列表有多种取值方式,可以直接读取in后面的值,默认 ...

  10. oracle常用查询sql

    oracle常用查询sql 原创 gordon陈 发布于2018-05-10 22:32:18 阅读数 297 收藏 展开 #!/bin/sh## create by Gordon Chen echo ...