小程序---小程序列表项拖拽排序

一、拖拽效果图展示

首先,上个gif图看看效果

吐血测试了一天,目前还未发现bug。ps(拖拽效果仅在前端实现,未和后端交互)

文章代码参考小程序实现列表拖拽排序 ,参考文章还是存在一些bug和不足,比如,样式代码没给对,还有实现的拖拽是拖拽起始位置数据的替换,不是我想要的拖拽效果。

二、解决思路

首先,拖拽重要的计算清楚位置关系,从什么地方开始拖,拖到什么地方结束,以及如何判断有效的拖拽排序。

在拖拽开始时、拖拽过程中、拖拽结束时获取拖拽数据项的索引和实时的位置相关数据。给拖拽节点绑定catchtouchstart、catchtouchmove、catchtouchend事件,利用data-xxx属性传递索引)

  <!-- 拖拽节点 --><view data-index='{{index}}' catchtouchstart='dragStart' catchtouchmove='dragMove'catchtouchend='dragEnd'><image class="img" src="/image/icon-sort.png"></image></view>

结合下图进行分析,如图,需要拖拽的数据列表都放在class=habitlist的节点中,为方便计算位置,固定每个数据项的height=60px;假设数据列表habitList=[{ name: "跳舞",icon: "./image/icon/icon-dance.png"},{name:"看书",...},...],当前拖拽项(name为跳舞的项)的克隆为kelong={name: "跳舞",icon: "./image/icon/icon-dance.png"}

1、【catchtouchstart】-拖拽开始时,获取当前拖拽项的索引,克隆当前项的内容给对象kelong。通过节点查询器,选择class=habitlist的节点,获取节点位置信息的查询请求,rect.top为该节点距离顶部的距离;rec.height为该节点区域的高度;e.changedTouches[0].clientY代表当前点击位置距离可视区域顶部的垂直距离,由于每个数据项的height=60px;预估:top=.changedTouches[0].clientY - rect.top - 30为当前克隆项显示的top,注意:克隆项显示的位置要相对class=habitlist的节点定位(子绝父相)。该值也为拖拽开始时的kelong项的位置startTop,(startTop值主要用于拖拽结束时判断是向下还是向上拖拽了)

  // 拖拽开始dragStart(e) {// console.log("拖拽开始", e);var i = e.currentTarget.dataset.index // 当前拖拽项的索引index// 把当前拖拽项的内容复制给kelongvar kelong = this.data.habitList[i]var query = wx.createSelectorQuery()  // 创建节点查询器 quer//选择class=habitlist的节点,获取节点位置信息的查询请求query.select('.habitlist').boundingClientRect((rect) => {var top = e.changedTouches[0].clientY - rect.top - 30var startTop = top;this.setData({kelong: kelong,selectedIndex:i,showkelong: true,top:top,startTop:startTop})}).exec();},

2、【catchtouchmove】-拖拽移动时,要对拖拽的范围做控制,文中做了顶部边界控制:控制克隆项不会拖拽出class=habitlist节点的顶部边界。当top<0时,将top置为0,底部可不做限制。

  // 拖拽移动dragMove(e) {// console.log("拖拽移动", e);var query = wx.createSelectorQuery();var top =this.data.topquery.select('.habitlist').boundingClientRect((rect) => {top = e.changedTouches[0].clientY - rect.top - 30if (top < 0) {// 顶部边界控制:控制克隆项不会拖拽出class=habitlist节点的顶部边界top = 0}this.setData({top:top})}).exec();},

3、【catchtouchend】-拖拽结束时,

(1)进行边界控制:不仅要进行顶部边界限制,还要做底部边界控制,即如果拖拽超出底部边界,则该拖拽数据项为最后一个位置的数据了。

(2)向上或向下拖拽的数据备份及处理:向上拖拽时,需要备份插入位置target开始的下方数据(除了拖拽数据项);向下拖拽时,需要备份插入位置target开始的上方数据;然后按拖拽后的正确索引位置遍历赋值。

// 拖拽结束dragEnd(e) {// console.log("拖拽结束", e);var i = e.currentTarget.dataset.indexvar query = wx.createSelectorQuery();var kelong = this.data.kelongvar habitList = this.data.habitListquery.select('.habitlist').boundingClientRect((rect) => {var top = e.changedTouches[0].clientY - rect.top - 30if (top > rect.height) {// 底部边界控制:控制克隆项拖拽结束时不会出class=habitlist节点的底部边界top = rect.height - 60} else if (top < 0) {// 顶部边界控制:控制克隆项拖拽结束时不会出class=habitlist节点的顶部边界top = 0}this.setData({top: top,})var target = parseInt(top / 60)var list = []  //用于备份数据if (this.data.startTop > top) {//  往上方位置拖拽for (var k = 0; k <= i - target; k++) {//  备份插入位置target开始的下方数据,除了拖拽数据项if (habitList[target + k].name != kelong.name) {list.push(habitList[target + k])}}if (list.lenghth != 0) {habitList[target] = kelongfor (var m = target + 1, n = 0; n < list.length; m++, n++) {habitList[m] = list[n]}}} else {// 往下边位置拖拽for (var k = 1; k <= target - i; k++) {//  备份插入位置target开始的上方数据,除了拖拽数据项if (habitList[i + k].name != kelong.name) {list.push(habitList[i + k])}}if (list.length != 0) {habitList[target] = kelongfor (var m = i, n = 0; n < list.length; m++, n++) {habitList[m] = list[n]}}}this.setData({habitList: habitList,selectedIndex:-1,showkelong: false})}).exec();},

三、完整代码

【sortHabit.wxml】

<view  class="page-wrapper"><top-title toptitle="排序习惯" backImgFlag="true"></top-title><view class="habitlist"><!-- 克隆当前拖拽的项 --><view class='habit kelong' hidden='{{!showkelong}}' style='top:{{top}}px'><view class='index'>?</view><view class="icon"><image class="iconImg" src="{{kelong.icon}}"></image></view><view class="info"><view class="title">{{kelong.name}}</view></view><image class="img"src="cloud://xbd-cloud-xxx/icon/icon-sort.png"></image></view><block wx:for="{{habitList}}" wx:key="name"><view class="habit {{selectedIndex==index?'gray':''}}" ><view class='index'>{{index+1}}</view><view class="icon"><image class="iconImg" src="{{item.icon}}"></image></view><view class="info"><view class="title">{{item.name}}</view></view><!-- 拖拽节点 --><view data-index='{{index}}' catchtouchstart='dragStart' catchtouchmove='dragMove'catchtouchend='dragEnd'><image class="img"src="cloud://xbd-cloud-xxx/icon/icon-sort.png"></image></view></view></block></view>
</view>

【sortHabit.js】

Page({/*** 页面的初始数据*/data: {habitList: [],// 当前拖拽项的克隆kelong: {name: '',icon: ''},startTop: 0, //拖拽开始时克隆项距离class=habitlist节点顶部边界的值top: 0,selectedIndex: -1, //被选择拖拽的项的indexbackupList: [], //用于备份数据showkelong: false, //是否显示克隆项},/*** 生命周期函数--监听页面加载*/onLoad: function (options) {var list = [{name: "跳舞",icon: "cloud://xbd-cloud-xxx/icon/icon-dance.png"}, {name: "看书",icon: "cloud://xbd-cloud-xxx/icon/icon-reading.png"}, {name: "运动",icon: "cloud://xbd-cloud-xxx/icon/icon-sports.png"}, {name: "护肤",icon: "cloud://xbd-cloud-xxx/icon/icon-facialmask.png"}]this.setData({habitList: list})},// 拖拽开始dragStart(e) {// console.log("拖拽开始", e);var i = e.currentTarget.dataset.index // 当前拖拽项的索引index// 把当前拖拽项的内容复制给kelongvar kelong = this.data.habitList[i]console.log("拖拽开始i=",i,"kelong=",kelong);var query = wx.createSelectorQuery(); // 创建节点查询器 quer//选择class=habitlist的节点,获取节点位置信息的查询请求query.select('.habitlist').boundingClientRect((rect) => {var top = e.changedTouches[0].clientY - rect.top - 30var startTop = top;this.setData({kelong: kelong,selectedIndex:i,showkelong: true,top:top,startTop:startTop})}).exec();},// 拖拽移动dragMove(e) {// console.log("拖拽移动", e);var query = wx.createSelectorQuery();var top =this.data.topquery.select('.habitlist').boundingClientRect((rect) => {top = e.changedTouches[0].clientY - rect.top - 30if (top < 0) {// 顶部边界控制:控制克隆项不会拖拽出class=habitlist节点的顶部边界top = 0}this.setData({top:top})}).exec();},// 拖拽结束dragEnd(e) {// console.log("拖拽结束", e);var i = e.currentTarget.dataset.indexvar query = wx.createSelectorQuery();var kelong = this.data.kelongvar habitList = this.data.habitListquery.select('.habitlist').boundingClientRect((rect) => {var top = e.changedTouches[0].clientY - rect.top - 30if (top > rect.height) {// 底部边界控制:控制克隆项拖拽结束时不会出class=habitlist节点的底部边界top = rect.height - 60} else if (top < 0) {// 顶部边界控制:控制克隆项拖拽结束时不会出class=habitlist节点的顶部边界top = 0}this.setData({top: top,})var target = parseInt(top / 60)var list = []  //用于备份数据if (this.data.startTop > top) {//  往上方位置拖拽for (var k = 0; k <= i - target; k++) {//  备份插入位置target开始的下方数据,除了拖拽数据项if (habitList[target + k].name != kelong.name) {list.push(habitList[target + k])}}console.log("往上拖拽 list=======", list);if (list.lenghth != 0) {habitList[target] = kelongfor (var m = target + 1, n = 0; n < list.length; m++, n++) {habitList[m] = list[n]}}} else {// 往下边位置拖拽for (var k = 1; k <= target - i; k++) {//  备份插入位置target开始的上方数据,除了拖拽数据项if (habitList[i + k].name != kelong.name) {list.push(habitList[i + k])}}console.log("往下拖拽 list=======", list);if (list.length != 0) {habitList[target] = kelongfor (var m = i, n = 0; n < list.length; m++, n++) {habitList[m] = list[n]}}}console.log(habitList);this.setData({habitList: habitList,selectedIndex:-1,showkelong: false})}).exec();},})

【sortHabit.wxss】

.habit {margin: 0rpx auto;width: 100%;height: 60px;border-radius: 10rpx;background-color: #fff;display: flex;padding: 15rpx;box-sizing: border-box;position: relative;border-bottom: 1px solid #f1f1f1;
}
.habit .index {margin: 25rpx 20rpx 0px 30rpx;font-weight: bold;color: #c93a3a;
}
.habit .icon {margin-right: 25rpx;
}
.habit .icon .iconImg {margin-top: 10rpx;width: 70rpx;height: 70rpx;
}
.habit .info {display: flex;flex-direction: column;width: 60vw;
}
.habit .info .title {margin: 25rpx 0rpx;font-size: 30rpx;
}
.habit .img {position: absolute;right: 30rpx;margin-top: 25rpx;width: 40rpx;height: 40rpx;
}
.habitlist {position: relative;
}
.kelong {z-index: 999;position: absolute;box-shadow: 1px 1px 5px #ccc;
}
.gray {background-color: #efecec;
}

ps:也不知道自己讲清楚没,记录点滴心路历程~下篇讲讲日历打卡

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/143543.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

微信小程序列表页

我们在做Android开发时,几乎每个app都有几个列表,在Android中列表一般是用listview&#xff0c;后来就使用recyclerview做了,不管是小程序还是Android或者ios&#xff0c;列表都是常见的一种数据展示方式,那么在小程序中怎么实现呢&#xff1f;先使用最笨的方法做, 如图&#…

微信小程序信息展示列表

微信小程序信息展示列表 效果展示: 代码展示: wxml <view class"head"><view class"head_item">分类</view><view class"ring"></view><view class"head_item">价格</view> </view>…

微信小程序列表开发-个人中心界面(一)

先放个效果图让你们看一下是不是你们需要的&#xff0c;到时候会写几篇博客把里面的组件也讲一下 .wxml .wxss .js .json 我里面的引用的照片都放在image文件里的&#xff0c;image文件是放在pages文件下面的&#xff0c;因为放的位置不同&#xff0c;图片引用的路径…

JDK8-JDK17中的新特性(var类型推断、模式匹配、Record、密封类)

文章目录 1. 新语法结构1.1 Java的REPL工具&#xff1a; jShell命令1.2 异常处理之try-catch资源关闭1.3 局部变量类型推断1.4 instanceof的模式匹配1.5 switch表达式1.6 文本块1.7 Record1.8 密封类 2. API的变化2.1 Optional类2.2 String存储结构和API变更2.3 JDK17&#xff…

linux下安装使用dig命令

有时候用的精简版linux系统会发现没有dig命令,这时候就需要安装一下。 centos系 yum install bind-utils dig命令大多时候可以取代nslookup 简明使用,只会输出A记录(写脚本的时候容易获取ip地址) dig www.baidu.com +short只输出mx记录,简明使用 dig mx www.baidu.com…

dig命令后+trace的含义

dig trace命令 dig ip 域名 类型 trace工作过程 以 dig pbc.gov.cn trace 为例。 用户看到的结果 wireshark抓包看到的结果&#xff08;只显示了查询部分&#xff0c;响应就是查询目的对源地址的响应&#xff09; 步骤源目的查询1本机ip中指定的ip.的NS2本机本地DNS.的NS…

linux dig命令使用详解

linux dig命令使用详解 Linux下解析域名除了使用nslookup之外&#xff0c;开可以使用dig命令来解析域名&#xff0c;dig命令可以得到更多的域名信息。dig 命令主要用来从 DNS 域名服务器查询主机地址信息。 dig的全称是 (domain information groper)。它是一个用来灵活探测DN…

dig命令笔记

dig 命令全称域信息搜索器&#xff0c;是一个用于查询 DNS 域名服务器信息的命令行工具。因为dig命令灵活&#xff0c;容易使用&#xff0c;多数DNS管理员使用dig命令来诊断 DNS 问题。 dig 常用命令格式 dig [server] [-p port] [-t type] [-4] [-6] [trace] name 指定 DNS …

linux中dig 命令解释

dig&#xff08;域信息搜索器&#xff09;命令是个用于询问 DNS 域名服务器的灵活的工具。他执行 DNS 搜索&#xff0c;显示从受请求的域名服务器返回的答复。多数 DNS 管理员利用 dig 作为 DNS 问题的故障诊断&#xff0c;因为他灵活性好、易用、输出清楚 1、A记录&#xff1…

从dig命令理解DNS

DNS&#xff08;Domain Name System&#xff0c;域名系统&#xff09;&#xff0c;是一种用于将域名解析为IP的服务器系统&#xff0c;当你上网时输入一个网址&#xff0c;它之所以能够找到该网址指向的服务器地址&#xff0c;都是靠域名系统来进行解析的。 先来讲讲域名。以华…

dig命令(dig命令怎么用)

林肯公园digdeeper是哪首歌 出自专辑《Minutes to Midnight》 nslookup、dig和host这几个命令有什么作用&#xff1f; nslookup、dig和host 这几个命令在UNIX和linux系统中使用,都可以进行域名的解析?nslookup使用交互方式查询域名与IP地址的映射关系?dig的功能是发送域名查…

Windows10 下安装 dig 命令的步骤(一)

前言&#xff1a; 今天在电脑上解析域名&#xff0c;但是发现dig命令报以下错误&#xff1a; Dig 工具全称为域名信息搜索器&#xff08;Domain InformationGroper&#xff09;&#xff0c;能够显示详细的DNS查询过程&#xff0c;是一个非常强大的DNS故障诊断工具。一般Linux…

linux中dig命令返回结果解释

dig baidu.com 返回 下面说明各项意义&#xff1a; ; <<>> DiG 9.3.6-P1-RedHat-9.3.6-20.P1.el5_8.6 <<>> baidu.com ;; global options: printcmd dig程序的版本号&#xff0c;和要查询的域名 Dig的部分输出告诉我们一些有关于它的版本信息(versio…

Windows系统下安装dig命令

dig 是一个 Linux 下用来 DNS 查询信息的工具&#xff0c;全称是Domain Information Groper&#xff0c;与 nslookup 类似&#xff0c;但比 nslookup 功能更强大。Windows 下只有 nslookup&#xff0c;如果也想用到 dig 命令&#xff0c;就只能自己动手安装了。 dig 作为 bind …

(学习日记)AD学习 #4

写在前面&#xff1a; 由于时间的不足与学习的碎片化&#xff0c;写博客变得有些奢侈。 但是对于记录学习&#xff08;忘了以后能快速复习&#xff09;的渴望一天天变得强烈。 既然如此 不如以天为单位&#xff0c;以时间为顺序&#xff0c;仅仅将博客当做一个知识学习的目录&a…

Excel表格匹配合并

在日常的工作中&#xff0c;免不了存在多个表格根据相同数据匹配合并的情况&#xff0c;很多人会因为复杂的公式导致匹配失败或错误。接下来&#xff0c;我将用一个简单的方式完成这一个任务。 1、打开网址www.excelutil.com 2、选择匹配合并 3、上传左文件和右文件 这两个文…

Excel模糊匹配相同内容的数据求和,使用SUMIF函数

看到朋友在对Excel表格数据进行机械操作&#xff0c;想到excel应该是个很强大的应用&#xff0c;这些机械操作应该可以通过函数简化操作的&#xff0c;于是不正经的研究下。 首先我们上图&#xff1a; 简单的需求&#xff0c;把每个店铺的每个月充值分别是200,500,1000,1500,2…

大模型时代的prompt学习(持续更新)

目录 为什么要学prompt基本原则prompt撰写框架Base Prompt FrameworkCRISPE Prompt Framework 场景撰写文案文档竞品分析产品设计数据分析 chain of thoughtzero shotin context learning(few shot)Self-Consistency Program-Aidedprompt tipsTo Do and Not To Doadd examples引…

excel数据分析 - 8个关联匹配类函数

1. LOOKUP函数 ①单条件定位查找 lookup( 待匹配内容, 待匹配内容所在区域 , 结果范围显示区域 ) 两个区域的列数需相同 e.g. 查找 “东区”对应的C1省会城市&#xff0c; lookup &#xff08;A2, A:A , C:C &#xff09; 杭州 A1B1C1东区 浙江杭州西区甘肃兰州 ②多条…

python excel 数据匹配_python将一个excel表格的数据匹配到另一个表中

python将一个excel表格的数据匹配到另一个表中 python将一个excel表格的数据匹配到另一个表中 打开excel表&#xff0c;需要在另一个表中匹配相应学生姓名的学号信息。 之前尝试了excel中的VLOOKUP函数&#xff0c;试了很多次都没有成功&#xff0c;因此&#xff0c;用python试…