react 移动端实现列表左滑删除的示例代码


Posted in Javascript onJuly 04, 2019

最近做了一个类似系统操作的左滑删除的demo,用的taro框架,和大家分享一下~

首先需要考虑的有以下几点:

1)布局;
2)判断是左滑还是右滑,左滑时出现删除,右滑时回归原位;
3)排他性,意思是某一个时间只能有一个项出现删除,当有另一个出现删除时,上一个自动回归原位。

我将列表项封装成一个组件,而整个列表是另一个组件。

接下来先说列表项这个组件,逐一解决以上这些问题:

1)布局

我采用的是列表项最外层套一个盒子,这个盒子宽度设置为100vw,并且overflow:hidden。而列表项要包括内容和删除按钮,内容宽度为屏幕宽度,而删除按钮定位到右边,所以整个列表项宽度是超过100vw的。描述可能没有那么清晰,直接上代码:

<View className='swipe-item'>
  <View className='swipe-item-wrap' style={moveStyle}>
   <View
    className='swipe-item-left'
    onTouchStart={this.handleTouchStart}
    onTouchMove={this.handleTouchMove.bind(this, index)}
    onTouchEnd={this.handleTouchEnd}
   >
    <View>{item.title}</View>
   </View>
   <View className='swipe-item-right'>
    <View className='swipe-item-del'>del</View>
   </View>
  </View>
</View>

.swipe-item {
 width: 100vw;
 overflow: hidden;
 line-height: 24PX;
 height: 24PX;
 text-align: center;
 margin-bottom: 10PX;

 &-wrap {
  width: calc(100vw + 32PX);
  height: 100%;
  position: relative;
 }

 &-left {
  width: 100vw;
 }

 &-right {
  width: 32PX;
  height: 100%;
  background: pink;
  position: absolute;
  right: 0;
  top: 0;
 }
}

好了,布局结束之后,接下来是第二个问题:

2)判断是左滑还是右滑,左滑时出现删除,右滑时回归原位

可以看到上面的代码,我已经在列表项左边部分加了touch的一系列事件,下面就来分析下这几个事件

  • touchstart:开始时,要获取当前位置
  • touchmove:滑动时,获取滑动时的位置,同时纵向滑动时阻止。来判断当前是左滑还是右滑,左滑时e.touches[0].pageX在减小,而右滑时变大。为了防止一个手误操作,我加了一个判断,当滑动超过一定距离时才动。并且记录下当前滑动的是第几项。在render的时候给列表项加一个样式就可以实现了,就是第一段代码中的style。
  • touchend:滑动结束

上代码了~

handleTouchStart = e => { 
  this.startX = e.touches[0].pageX
  this.startY = e.touches[0].pageY
 }

 handleTouchMove (index, e) {
  // 若想阻止冒泡且最外层盒子为scrollView,不可用e.stopPropogagation(),否则页面卡死
  this.currentX = e.touches[0].pageX
  this.moveX = this.currentX - this.startX
  this.moveY = e.touches[0].pageY - this.startY
  // 纵向移动时return
  if (Math.abs(this.moveY) > Math.abs(this.moveX)) {
   return
  }
  // 滑动超过一定距离时,才触发
  if (Math.abs(this.moveX) < 10 ) {
   return
  }
  else {
   // 否则没有动画效果
   this.setState({
    hasTransition: true
   })
  }
  // 通知父组件当前滑动的为第几项
  this.props.onSetCurIndex(index)
 }

 handleTouchEnd = e => {
  // 结束时,置为true,否则render时不生效
  this.setState({
   hasTransition: true
  })
 }

3)排他性

这个主要是通过触发父组件的一个事件,在父组件中设置一个当前滑动项的index值,然后再通过props值传入子组件,渲染的时候加一个判断实现。

// 左滑时,出现del,右滑时,恢复原位,距离为操作按钮大小
// 也可以将滑动距离作为移动距离,但是效果不太好
const distance = this.moveX >= 0 ? 0 : -32
let moveStyle = {}
// 排他性,若某一个处于滑动状态时,其他都回归原位
if (hasTransition && currentIndex === index) {
 moveStyle.transform = `translateX(${distance}PX)`
 moveStyle.webkitTransform = `translateX(${distance}PX)`
 moveStyle.transition = 'transform 0.3s ease'
 moveStyle.WebkitTransition = 'transform 0.3s ease'
}

列表项就到此结束了,下面来说列表组件中调用列表项~

handleCurIndex = index => {
  // 设置当前滑动项,做排他性
  this.setState({
   currentIndex: index
  })
}

<SwipeItem
 item={item}
 key={item.id}
 index={index}
 currentIndex={currentIndex}
 onSetCurIndex={this.handleCurIndex}
/>

好了,大致就是这些了,可能有点混乱,大家可以移步demo源码~

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
纯js实现背景图片切换效果代码
Nov 14 Javascript
jQuery调用ajax请求的常见方法汇总
Mar 24 Javascript
由简入繁实现Jquery树状结构的方法(推荐)
Jun 10 Javascript
老生常谈js动态添加事件--- 事件委托
Jul 19 Javascript
浅谈jQuery双事件多重加载的问题
Oct 05 Javascript
jquery实现输入框实时输入触发事件代码
Dec 21 Javascript
js模态对话框使用方法详解
Feb 16 Javascript
vue axios 二次封装的示例代码
Dec 08 Javascript
JavaScript arguments.callee作用及替换方案详解
Sep 02 Javascript
jQuery实现简单三级联动效果
Sep 05 jQuery
vue+iview实现分页及查询功能
Nov 17 Vue.js
详解Vue的options
May 15 Vue.js
jQuery删除/清空指定元素的所有子节点实例代码
Jul 04 #jQuery
小程序中canvas的drawImage方法参数使用详解
Jul 04 #Javascript
vue如何限制只能输入正负数及小数
Jul 04 #Javascript
Vue项目中ESlint规范示例代码
Jul 04 #Javascript
你或许不知道的一些npm实用技巧
Jul 04 #Javascript
中高级前端必须了解的JS中的内存管理(推荐)
Jul 04 #Javascript
angular6开发steps步骤条组件
Jul 04 #Javascript
You might like
在PHP中使用curl_init函数的说明
2010/11/02 PHP
fleaphp常用方法分页之Pager使用方法
2011/04/23 PHP
php获取mysql字段名称和其它信息的例子
2014/04/14 PHP
phpMyAdmin安装并配置允许空密码登录
2015/07/04 PHP
PHP精确计算功能示例
2016/11/29 PHP
PHP chop()函数讲解
2019/02/11 PHP
JavaScript实现的简单拖拽效果
2015/06/01 Javascript
bootstrap下拉列表与输入框组结合的样式调整
2016/10/08 Javascript
KnockoutJS 3.X API 第四章之数据控制流foreach绑定
2016/10/10 Javascript
CentOS 安装NodeJS V8.0.0的方法
2017/06/15 NodeJs
Angular2环境搭建具体操作步骤(推荐)
2017/08/04 Javascript
JavaScript实现的仿新浪微博原生态输入字数即时检查功能【兼容IE6】
2017/09/26 Javascript
layui 设置table 行的高度方法
2018/08/17 Javascript
vue elementUI tree树形控件获取父节点ID的实例
2018/09/12 Javascript
layui 实现二级弹窗弹出之后 关闭一级弹窗的方法
2019/09/18 Javascript
vue element upload组件 file-list的动态绑定实现
2019/10/11 Javascript
[09:33]2015国际邀请赛第四日TOP10
2015/08/08 DOTA
Python 如何访问外围作用域中的变量
2016/09/11 Python
用pickle存储Python的原生对象方法
2017/04/28 Python
Django-Rest-Framework 权限管理源码浅析(小结)
2018/11/12 Python
Python基于数列实现购物车程序过程详解
2020/06/09 Python
联想墨西哥官方网站:Lenovo墨西哥
2016/08/17 全球购物
菲律宾领先的在线时尚商店:Zalora菲律宾
2018/02/08 全球购物
世界上最大的在线汽车租赁预订平台:Rentalcars.com(支持中文)
2018/10/12 全球购物
澳大利亚家具和家居用品购物网站:Zanui
2018/12/29 全球购物
英国最好的包装供应商:Priory Direct
2019/12/17 全球购物
LUISAVIAROMA德国官网:时尚奢侈品牌购物网站
2020/11/12 全球购物
Python中如何定义一个函数
2016/09/06 面试题
教师试用期自我鉴定
2014/02/12 职场文书
二年级语文上册复习计划
2015/01/19 职场文书
捐助感谢信
2015/01/22 职场文书
体育教师个人总结
2015/02/09 职场文书
小学六一主持词开场白
2015/05/28 职场文书
教师节作文之小学四年级
2019/09/03 职场文书
goland 设置project gopath的操作
2021/05/06 Golang
详解Flutter和Dart取消Future的三种方法
2022/04/07 Java/Android