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

 
实现效果

JS

  1. Page({
  2. /**
  3. * 页面的初始数据
  4. */
  5. data: {
  6. optionList: [],
  7. movableViewInfo: {
  8. y: 0,
  9. showClass: 'none',
  10. data: {}
  11. },
  12. pageInfo: {
  13. rowHeight: 47,
  14. scrollHeight: 85,
  15. startIndex: null,
  16. scrollY: true,
  17. readyPlaceIndex: null,
  18. startY: 0,
  19. selectedIndex: null,
  20. }
  21. },
  22. dragStart: function (event) {
  23. var startIndex = event.target.dataset.index
  24. console.log('获取到的元素为', this.data.optionList[startIndex])
  25. // 初始化页面数据
  26. var pageInfo = this.data.pageInfo
  27. pageInfo.startY = event.touches[0].clientY
  28. pageInfo.readyPlaceIndex = startIndex
  29. pageInfo.selectedIndex = startIndex
  30. pageInfo.scrollY = false
  31. pageInfo.startIndex = startIndex
  32. this.setData({
  33. 'movableViewInfo.y': pageInfo.startY - (pageInfo.rowHeight / 2)
  34. })
  35. // 初始化拖动控件数据
  36. var movableViewInfo = this.data.movableViewInfo
  37. movableViewInfo.data = this.data.optionList[startIndex]
  38. movableViewInfo.showClass = "inline"
  39. this.setData({
  40. movableViewInfo: movableViewInfo,
  41. pageInfo: pageInfo
  42. })
  43. },
  44. dragMove: function (event) {
  45. var optionList = this.data.optionList
  46. var pageInfo = this.data.pageInfo
  47. // 计算拖拽距离
  48. var movableViewInfo = this.data.movableViewInfo
  49. var movedDistance = event.touches[0].clientY - pageInfo.startY
  50. movableViewInfo.y = pageInfo.startY - (pageInfo.rowHeight / 2) + movedDistance
  51. console.log('移动的距离为', movedDistance)
  52. // 修改预计放置位置
  53. var movedIndex = parseInt(movedDistance / pageInfo.rowHeight)
  54. var readyPlaceIndex = pageInfo.startIndex + movedIndex
  55. if (readyPlaceIndex < 0 ) {
  56. readyPlaceIndex = 0
  57. }
  58. else if (readyPlaceIndex >= optionList.length){
  59. readyPlaceIndex = optionList.length - 1
  60. }
  61. if (readyPlaceIndex != pageInfo.selectedIndex ) {
  62. var selectedData = optionList[pageInfo.selectedIndex]
  63. optionList.splice(pageInfo.selectedIndex, 1)
  64. optionList.splice(readyPlaceIndex, 0, selectedData)
  65. pageInfo.selectedIndex = readyPlaceIndex
  66. }
  67. // 移动movableView
  68. pageInfo.readyPlaceIndex = readyPlaceIndex
  69. // console.log('移动到了索引', readyPlaceIndex, '选项为', optionList[readyPlaceIndex])
  70. this.setData({
  71. movableViewInfo: movableViewInfo,
  72. optionList: optionList,
  73. pageInfo: pageInfo
  74. })
  75. },
  76. dragEnd: function (event) {
  77. // 重置页面数据
  78. var pageInfo = this.data.pageInfo
  79. pageInfo.readyPlaceIndex = null
  80. pageInfo.startY = null
  81. pageInfo.selectedIndex = null
  82. pageInfo.startIndex = null
  83. pageInfo.scrollY = true
  84. // 隐藏movableView
  85. var movableViewInfo = this.data.movableViewInfo
  86. movableViewInfo.showClass = 'none'
  87. this.setData({
  88. pageInfo: pageInfo,
  89. movableViewInfo: movableViewInfo
  90. })
  91. },
  92. /**
  93. * 生命周期函数--监听页面加载
  94. */
  95. onLoad: function (options) {
  96. var optionList = [
  97. "段落1 内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容",
  98. "段落2 内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容",
  99. "段落3 内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容",
  100. "段落4 内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容",
  101. "段落5 内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容",
  102. "段落6 内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容",
  103. "段落7 内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容",
  104. "段落8 内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容",
  105. "段落9 内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容"
  106. ]
  107. this.setData({
  108. optionList: optionList
  109. })
  110. },
  111. })

WXML

  1. <view class='zhuti'>
  2. <view class='row title-row' style='height: {{pageInfo.rowHeight}}px;'>
  3. <view class="col1">信息</view>
  4. <view class="col2">详情</view>
  5. <view class="col3">排序</view>
  6. </view>
  7. <movable-area class='movable-area'
  8. style='display:{{movableViewInfo.showClass}}; height:{{pageInfo.scrollHeight}}%;'>
  9. <movable-view class='row list-row movable-row'
  10. out-of-bounds='true'
  11. damping='999'
  12. style='height:{{pageInfo.rowHeight}}px;'
  13. direction="vertical"
  14. y="{{movableViewInfo.y}}">
  15. <view class='col1 content' >{{movableViewInfo.data}}</view>
  16. <view class="col2" >
  17. <icon type='info' color='Gray' size='22' />
  18. </view>
  19. <view class="col3" >
  20. <icon type='download' color='Gray' size='25' />
  21. </view>
  22. </movable-view>
  23. </movable-area>
  24. <scroll-view scroll-y='{{pageInfo.scrollY}}' style='height: {{pageInfo.scrollHeight}}%'>
  25. <block wx:for='{{optionList}}'>
  26. <view class='row list-row {{pageInfo.readyPlaceIndex == index ? "ready-place" : ""}}' style='height: {{pageInfo.rowHeight}}px;'>
  27. <view class='col1 content' >{{item}}</view>
  28. <view class="col2" >
  29. <icon type='info' color='Gray' size='22'
  30. data-index='{{index}}'
  31. bindtap='showDetail'
  32. />
  33. </view>
  34. <view class="col3" >
  35. <icon type='download' color='Gray' size='25'
  36. data-index='{{index}}'
  37. bindtouchstart='dragStart'
  38. bindtouchmove='dragMove'
  39. bindtouchend='dragEnd'
  40. />
  41. </view>
  42. </view>
  43. </block>
  44. </scroll-view>
  45. </view>

WXSS

  1. page {
  2. height: 100%;
  3. width: 100%;
  4. }
  5. .zhuti {
  6. height: 100%;
  7. width: 100%;
  8. position: relative;
  9. }
  10. .row {
  11. height: 47px;
  12. width: 100%;
  13. display: flex;
  14. justify-content: space-around;
  15. align-items: center;
  16. }
  17. .title-row {
  18. border-bottom: 1px solid #888888;
  19. color: #888888;
  20. }
  21. .list-row {
  22. padding: 8px 0px;
  23. border-bottom: 1px solid #D9D9D9;
  24. background-color: white;
  25. }
  26. .movable-area {
  27. position: absolute;
  28. top: 0;
  29. left: 0;
  30. z-index: 10;
  31. width: 100%;
  32. }
  33. .movable-row {
  34. box-shadow: #D9D9D9 0px 0px 20px;
  35. }
  36. .col1 {
  37. width: 60%;
  38. }
  39. .col2 {
  40. width: 10%;
  41. }
  42. .col3 {
  43. width: 10%;
  44. }
  45. .ready-place {
  46. background-color: #CCCCCC
  47. }
  48. .content {
  49. font-size: 17px;
  50. white-space: nowrap;
  51. overflow: hidden;
  52. text-overflow: ellipsis;
  53. }

 

作者: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. 基于django的个人博客网站建立(七)

    基于django的个人博客网站建立(七) 前言 网站效果可点击这里访问 这次在原来的基础上添加或修改一些小功能 具体内容 1.代码高亮 在原来的blog-details.html页面添加下面的代码: ...

  2. 25.推荐---协同过滤(Collaborative Filtering)

    协同过滤需要注意的三点: gray sheep(有人喜欢追求特别,协同过滤一般只能从共同的人或物间找相似) shilling attack(水军刷好评导致数据错误,无法带来精确的推荐) cold st ...

  3. 三feng云,免费虚拟主机和免费云服务器

    三feng云,免费虚拟主机和免费云服务器 链接:https://www.sanfengyun.com 虚拟主机 虚拟服务器 BGP多线路 独立IP地址 送免备案系统,永久免费 具备高在线率.高安全性. ...

  4. swoole比php好在哪里

    直接套用Swoole官网的介绍: PHP的异步.并行.高性能网络通信引擎,使用纯C语言编写,提供了PHP语言的异步多线程服务器,异步TCP/UDP网络客户端,异步MySQL,异步Redis,数据库连接 ...

  5. 关于Excel做表小知识记录

    关于Excel做表小知识记录 最近使用Excel做了一系列的报表,觉得这是个很神奇的东西哈哈哈,以前我可是一想到Excel就开始头疼的人...  能用代码或者SQL语句解决的问题绝不会愿意留在Exce ...

  6. SpringBoot系列——Filter 过滤器

    前言 本文记录一下在SpringBoot项目中是如何使用Filter过滤器 代码.测试 Filter过滤器是servlet包下面的东西,因此我们不需要再额外引包 方法一 直接实现Filter接口,并使 ...

  7. PHPStorm 配置本地 WebServer 运行 PHP

    目标:PHPStorm 2018.2 通过配置运行 PHP 代码无需安装其它 Web Server File -> Settings菜单找到PHP,设置 CLI Interpreter PHP的 ...

  8. jq初始,选择器,事件,内容操作,样式操作

    jq操作页面文档http://jquery.cuishifeng.cn/ jq初始 <!DOCTYPE html> <html> <head> <meta c ...

  9. expect 知识与示例说明

    expect 知识与示例说明 2012/04/10 chenxin 2019/07/07 update Chenxin 参考 https://www.cnblogs.com/yinghao1991/p ...

  10. Linux-3.14.12内存管理笔记【构建内存管理框架(1)】

    传统的计算机结构中,整个物理内存都是一条线上的,CPU访问整个内存空间所需要的时间都是相同的.这种内存结构被称之为UMA(Uniform Memory Architecture,一致存储结构).但是随 ...