当前位置:   article > 正文

移动端左右滑动出现和隐藏按钮(适合vue和小程序开发)_vue3.0 移动端从右往左滑 显示功能按钮

vue3.0 移动端从右往左滑 显示功能按钮

在日常开发中,会碰到许许多多的样式布局,有时候用ui框架并不是特别的符合项目的需求,所以有的时候还是要自己亲自动手来写,这是一个简单的,左右滑动可以显示和隐藏删除按钮的一个小demo,大家可以相互学习学习,如果哪里表达的不太好,欢迎大家来指正,或者有更好的实现方法也可以评论,希望大佬们多多提意见。

首先来看一下效果图

首先先和大家说一下我的思路,最后把代码放到后边供大家参考

第一:首先我们先想一下应该怎样布局,肯定这个删除按钮是存在的,然后用户从右向左滑动的时候我们把它显示出来,然后从左向右滑动的时候我们在把这个删除按钮给隐藏掉。

这个时候我们可以这样去想,比如最外边的盒子来一个li,然后给这个li设置一个100%的宽度,然后li里面放一个盒子起一个类名比如叫.libox,这个libox的宽度给它设置成120%(当然这里写都成vw的单位也是可以的)。然后给li添加overflow:hidden,我们可以在libox中使用flex布局,分成3部分,左边的商品信息,中间的步进器,和右边的删除按钮,当然在这里第一部分和第二部分要站100%的宽度,自然右侧的删除按钮就显示不出来了。然后给这个libox盒子添加一个相对定位,然后只需控制libox的left属性为0和-20%即可。当然可以加一点过渡效果transition,不过加了过渡最好使用transform来移动libox。

第二:基本样式做好以后,我们再考虑一下怎样能让它滑动起来。

这里告诉大家两个移动端的事件

  1. ontouchstart // 手指按下时触发
  2. ontouchmove // 手指在屏幕上移动时触发

我们知道这两个事件以后就简单了,大家可以这样想,我们在ontouchstart事件中拿到当前手指触碰的x轴上的位置,然后滑动的时候我们在ontouchmove事件中拿到用户滑动以后x轴上的位置,然后用ontouchstart中x轴上的位置减去ontouchmove中x轴上的位置,比如他们两个之差大于20,则我就控制libox的transform:transform: translateX(-20vw)即可。同样如果小于20后,我就控制libox的transform:transform: translateX(20vw)即可。

但是,还有一个问题就是,不管我们是在vue中还是小程序中,购物车里可能会有好几个商品,那么我们一般是从服务器拿到数据以后通过v-for或者wx:for来遍历出来这些libox,因为这些libox有着同样的一些属性和类名,那么我们怎样确定我们当前滑动的是哪个libox呢,就是我该怎样获取当前滑动的这个liboxDOM元素呢,我只有获取到了这个liboxDOM才能对其进行操作,libox.style.left=-20%如果写成document.querySelector('.libox')它拿到的又是哪个libox盒子呢?如果不确定我们当前滑动的是哪个libox的话,那么我们随便滑动一个libox,然后所有的libox就都会显示出删除按钮。所以我们可以换一种思路。

思路是这样的:

我们可以提前写好一个类名,比如就叫.isleft吧,然后这个类里边的css写上一个transform: translateX(-20vw),然后我们在data属性中定义一个状态就叫isleft给他一个初始值为-1,然后我在这个要遍历的libox盒子上通过三元表达式来判断是否给当前的这个libox加上.isleft这个类名(哪个libox加上.isleft类名后,哪个libox中的删除按钮就会显示出来),可以用data属性中的isleft状态来和当前libox的index值来进行匹配。然后在滑动事件中来对data属性中的isleft状态进行改变。在libox的滑动事件中把当前的libox index值传到滑动事件中,然后在滑动事件中对isleft状态赋值,赋成libox传递过来的index的值,然后当在libox这个盒子的html结构中通过三元表达式来判断isleft==index,从而达到我滑动哪个libox,哪个libox的删除按钮就会显示出来。

以下是具体代码:(以小程序为例,vue大同小异,只要把思路想清楚vue用同样的方法实现)

html部分

  1. <view class="ul">
  2. <view class="li" data-id="{{index}}" bindtouchstart="hStart" bindtouchmove="hMove" wx:for="{{aaa}}" wx:key="*this">
  3. <view class="libox {{isleft==index ? 'isleft' : ''}}">
  4. <view class="li_content">
  5. <checkbox></checkbox>
  6. <image src="{{item.url}}"></image>
  7. <view class="context">
  8. <view>{{item.name}}</view>
  9. <view style="color: darkred;">{{item.price}}</view>
  10. </view>
  11. </view>
  12. <view class="li_step">
  13. <view class="step">
  14. <text>-</text>
  15. <text>1</text>
  16. <text>+</text>
  17. </view>
  18. </view>
  19. <view class="del" bindtap="delgoods">删除</view>
  20. </view>
  21. </view>
  22. </view>

css部分

  1. .li {
  2. width: 100%;
  3. overflow: hidden;
  4. margin-top: 30rpx;
  5. box-shadow: 8rpx 8rpx 8rpx #F8F8FF;
  6. }
  7. .li .libox{
  8. position: relative;
  9. width: 120%;
  10. height: 200rpx;
  11. display: flex;
  12. justify-content: space-between;
  13. padding: 10rpx 0 10rpx 20rpx;
  14. box-sizing: border-box;
  15. transition: all .5s;
  16. }
  17. .li .li_step {
  18. position: relative;
  19. width: 30%;
  20. }
  21. .li .li_step .step {
  22. position: absolute;
  23. height: 70rpx;
  24. border-radius: 10rpx;
  25. overflow: hidden;
  26. width: 195rpx;
  27. top: 50%;
  28. left: 50%;
  29. transform: translate(-50%,-50%);
  30. }
  31. .li .li_step text{
  32. display: inline-block;
  33. width: 65rpx;
  34. line-height: 70rpx;
  35. background-color: #f2f3f5;
  36. text-align: center;
  37. }
  38. .li .li_content {
  39. display: flex;
  40. width: 70%;
  41. line-height: 180rpx;
  42. box-sizing: border-box;
  43. justify-content: flex-start;
  44. padding: 0 20rpx;
  45. }
  46. .li .li_content image {
  47. width: 40%;
  48. overflow: hidden;
  49. height: 180rpx;
  50. margin: 0 20rpx;
  51. }
  52. .li .li_content .context {
  53. display: inline-block;
  54. width: 35%;
  55. margin-left: 20rpx;
  56. box-sizing: border-box;
  57. padding-top: 20rpx;
  58. }
  59. .li .li_content .context view {
  60. height: 70rpx;
  61. line-height: 70rpx;
  62. overflow: hidden;
  63. text-overflow: ellipsis;
  64. white-space: nowrap;
  65. }
  66. .del {
  67. width: 20%;
  68. line-height: 180rpx;
  69. text-align: center;
  70. background-color: #ee0a24;
  71. color: #fff;
  72. margin-left: 2%;
  73. }
  74. .isleft {
  75. transform: translateX(-20vw);
  76. }

js部分

  1. Page({
  2. data: {
  3. isleft: -1,
  4. aaa: [
  5. {
  6. url: 'http://localhost:5000/images/10/poster.jpg',
  7. name: '华为 HUAWEI Mate 30',
  8. price: '¥4499'
  9. },
  10. {
  11. url: 'http://localhost:5000/images/6/poster.jpg',
  12. name: 'Apple iPhone 11',
  13. price: '¥5999'
  14. }
  15. ]
  16. },
  17. xstar: 0,
  18. xmove: 0,
  19. // 生命周期函数--监听页面隐藏
  20. onHide: function () {
  21. // 这里是如果用户向左滑动了以后,没有滑动回去,删除按钮显示的时候,切换到别的页面,那么就让切换到别的页面以前把删除按钮给它隐藏回去在切出去别的页面,这样用户回来的时候看不到删除按钮
  22. this.setData({
  23. isleft: -1
  24. })
  25. },
  26. // hStart和hMove方法是判断用户左右滑动显示和隐藏删除按钮
  27. hStart(e) {
  28. this.xstar = e.touches[0].pageX
  29. },
  30. hMove(e) {
  31. this.xmove = e.touches[0].pageX
  32. let x = this.xstar - this.xmove
  33. if (x>20) {
  34. this.setData({
  35. isleft: e.currentTarget.dataset.id
  36. })
  37. } else {
  38. this.setData({
  39. isleft: -1
  40. })
  41. }
  42. },
  43. // 删除商品
  44. delgoods() {
  45. console.log('删除')
  46. }
  47. })

我也尝试过,在.isleft类中写成left:-20%,但是这样就没有过渡效果了(libox中已经加了transition了),显得很生硬。还有就是把transform: translateX(-20vw);写成transform: translateX(-20%);后,滑动出来删除按钮距离右侧有一点点小间距

可能是我写的css样式出了点小问题,宽度计算的不太准确,因为我还给libox加了一个padding值。

总之css中使用flex布局,不知道给多少宽度时候要么单位就都使用%,要么就都是用vw,不然两个单位混着用可能会出现问题,达不到想要布局的效果。 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/91745
推荐阅读
相关标签
  

闽ICP备14008679号