微信小程序购物车 滑动删除效果

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了微信小程序购物车 滑动删除效果相关的知识,希望对你有一定的参考价值。

参考技术A 往左边滑动出现删除按钮, 只对当前滑动的对象操作

<view class="shop-list">

    <view class="check-all-box" bindtap="onCheckAll">

      <view>

        <label class="check-around8"  bindtap="selected" data-lor='1'>

          <radio checked="allSelected?true:false" color="#000"></radio>

          <text class="check-all">checkAllText全选</text>

        </label> 

      </view>

    </view>

    <view class="item-box  item.isTouchMove ? 'touch-move-active' : ''" data-index="index" bindtouchstart="touchstart" bindtouchmove="touchmove" wx:for="list" wx:key="index">

      <view class="item">

        <view class="check-around-box" data-id="item.id" >

            <label bindtap="selected" data-id="item.id" data-isSelect="item.isSelect">

              <radio checked="item.isSelect>0?true:false" color="#000"></radio>

            </label>   

          </view>

        <view class="item-img-box">

          <image class="item-img" src="item.thumbUrl" />

        </view>

        <view class="item-info-box">

          <text class="item-title">item.title</text>

          <text class="item-spec">item.spec</text>

          <text class="item-price">¥item.price</text>

          <view class="num-box">

            <view class="num-desc" data-id="item.id" data-total="item.total" bindtap="reduce">-</view>

            <input class="item-input" type="number"disabled="boolean" value="item.total" />

            <view class="num-plus" data-id="item.id" data-total="item.total" bindtap="plus">+</view>

          </view>

        </view>

      </view>

      <view class="remove" data-id="item.id" bindtap="remove">remove删除</view>

    </view>

  </view>

page

  background-color: #f8f8f8;



.shop-list

  display: flex;

  flex-direction: column;

  margin-top: 30rpx;

  padding-bottom:120rpx;



.check-all-box

  display: flex;

  align-items: center;

  padding: 30rpx;

  background-color: #fff;



.check-all-box  .check-all

  margin-left: 20rpx;

  font-size: 30rpx;



.check-around

  width: 35rpx;

  height: 35rpx;

  margin-right:20rpx;

  border-radius: 50rpx;

  border: 1rpx solid #f8f8f8;



.check-active

  width: 35rpx;

  height: 35rpx;

  border-radius: 50rpx;

  background-color: #999999;



.item-box

  margin-bottom: 20rpx;

  position: relative;

  z-index: 99;

  font-size: 14px;

  display: flex;

  justify-content: space-between;

  border-bottom:1px solid #ccc;

  width: 100%;

  overflow: hidden



.item

  display: flex;

  align-items: center;

  padding: 30rpx;

  background-color: #fff;

  position: relative;

  z-index: 99;

  width: 100%;

  margin-right:0;

  -webkit-transition: all 0.4s;

  transition: all 0.4s;

  -webkit-transform: translateX(90px);

  transform: translateX(90px);

  margin-left: -90px



.item .item-img

  width: 180rpx;

  height: 180rpx;

  border-radius: 5rpx;

  border: 1rpx solid #eaeaea;



.item .item-info-box

  display: flex;

  flex-direction: column;

  justify-content: space-between;

  width: 420rpx;

  height: 180rpx;

  margin-left:20rpx;



.item-info-box .item-title

  font-size: 30rpx;

  white-space: nowrap;

  text-overflow: ellipsis;

  overflow: hidden;

  word-break: break-all;



.item-info-box .item-spec

  color: #676767;

  margin-top: 15rpx;

  text-overflow: -o-ellipsis-lastline;

  overflow: hidden;

  text-overflow: ellipsis;

  display: -webkit-box;

  -webkit-line-clamp: 2;

  line-clamp: 2;

  -webkit-box-orient: vertical;



.item-info-box .item-price

  display: flex;

  margin-top: 15rpx;



.item-info-box .num-box

  display: flex;

  align-items: center;

  justify-content: flex-end;

  font-size: 30rpx;



.num-box .num-desc

  padding: 0 10rpx;

  color: #999;

  border: 4rpx solid #999;



.num-box .item-input

  width: 80rpx;



.item-input

  text-align: center;



.num-box .num-plus

  padding: 0 10rpx;

  color: #fff;

  background-color: #000;

  border: 4rpx solid #000;



.remove

  background-color: orangered;

  width: 90px;

  display: flex;

  flex-direction: column;

  align-items: center;

  justify-content: center;

  color: #fff;

  -webkit-transform: translateX(90px);

  transform: translateX(90px);

  -webkit-transition: all 0.4s;

  transition: all 0.4s;



.touch-move-active .item,

.touch-move-active .remove

  -webkit-transform: translateX(0);

  transform: translateX(0);



var app = getApp()

Page(

  data:

    list: [

     

        id: '1',

        thumbUrl: 'https://cdnimg.pfhoo.com/Pro/s/20180404/8a22565d-9bb3-4b87-bf58-00e9db0e2d28.jpg',

        title: '大英博物馆珠宝首饰系列“OK”首饰',

        spec: 'K黄',

        price: '199.10',

        num: 1,

        total: 10

      ,

        id: '2',

        thumbUrl: 'https://cdnimg.pfhoo.com/Pro/s/20180404/8a22565d-9bb3-4b87-bf58-00e9db0e2d28.jpg',

        title: '大英博物馆珠宝首饰系列“OK”首饰',

        spec: 'K黄',

        price: '899.20',

        num: 1,

        total: 1

     

    ],

    startX: 0, //开始坐标

    startY: 0

  ,

  onLoad: function ()

  ,

  //手指触摸动作开始 记录起点X坐标

  touchstart: function (e)

    //开始触摸时 重置所有删除

    this.data.list.forEach(function (v, i)

      if (v.isTouchMove)//只操作为true的

        v.isTouchMove = false;

    )

    this.setData(

      startX: e.changedTouches[0].clientX,

      startY: e.changedTouches[0].clientY,

      list: this.data.list

    )

  ,

  //滑动事件处理

  touchmove: function (e)

    var that = this,

      index = e.currentTarget.dataset.index,//当前索引

      startX = that.data.startX,//开始X坐标

      startY = that.data.startY,//开始Y坐标

      touchMoveX = e.changedTouches[0].clientX,//滑动变化坐标

      touchMoveY = e.changedTouches[0].clientY,//滑动变化坐标

      //获取滑动角度

      angle = that.angle( X: startX, Y: startY , X: touchMoveX, Y: touchMoveY );

    that.data.list.forEach(function (v, i)

      v.isTouchMove = false

      //滑动超过30度角 return

      if (Math.abs(angle) > 30) return;

      if (i == index)

        if (touchMoveX > startX) //右滑

          v.isTouchMove = false

        else //左滑

          v.isTouchMove = true

     

    )

    //更新数据

    that.setData(

      list: that.data.list

    )

  ,

  /**

  * 计算滑动角度

  * @param Object start 起点坐标

  * @param Object end 终点坐标

  */

  angle: function (start, end)

    var _X = end.X - start.X,

      _Y = end.Y - start.Y

    //返回角度 /Math.atan()返回数字的反正切值

    return 360 * Math.atan(_Y / _X) / (2 * Math.PI);

  ,

  //删除事件

  remove: function (e)

    let that =this;

    let index = e.currentTarget.dataset.index;

    let list = that.data.list;

    wx.showModal(

      title: 'w温馨提示!',

      content: '你确认删除吗?',

      success: function (res)

        if (res.confirm)

          console.log('444')

          list.splice(index, 1)

          that.setData(

            list:list

          )

        else

          console.log('用户点击取消')

       

     

    )

 

)

微信小程序 向左滑动显示(删除修改)按钮

原理就是上下两个盒子,当上面的盒子向左滑动时显示出下面的盒子。
效果展示:

直接上代码,注释应该写的挺清楚的。

wxml


  <view class="list-item" wx:for="list" wx:key="id">
    <view class="item-btns">
        <image class="update" src="/icons/修改.png" bindtap="update"></image>
        <image class="delete" src="/icons/删除.png" bindtap="delete" data-id="item._id"></image>
    </view>
    <view class="item-cont" data-index="index" style="left:item.offsetXrpx" bindtouchstart="touchStart" catchtouchmove="touchMove" bindtouchend="touchEnd">
    </view>
  </view>


wxss


.list-item
  margin: 10rpx auto;
  width: 700rpx;
  height:130rpx;
  position:relative;

.item-btns
  display:flex;
  justify-content: flex-end;
  height: 100%;

.update
  width: 80rpx;
  height: 80rpx;
  background-color: pink;
  border-radius: 50%;
  margin-right: 20rpx;
  margin-top: 25rpx;

.delete
  width: 80rpx;
  height: 80rpx;
  background-color: pink;
  border-radius: 50%;
  margin-right: 30rpx;
  margin-top: 25rpx;

.item-cont
  border-radius: 15rpx;
  position:absolute;
  top:0rpx;
  left:0rpx;
  width:100%;
  height:100%;
  background:#ddd;


js

let recordStartX = 0, currentOffsetX = 0, curIndex = 0; //按下初始值,当前滑块初始值,当前滑块下标
Page(

  /**
   * 页面的初始数据
   */
  data: 
    list:[id:1,id:2,id:3],
    offsetWidth:-250, //上面的盒子向左滑动时,下面的盒子要显示出来的宽度,负号是指相对于起始位置向左滑动为负值
  ,

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) 
  ,
  
  touchStart: function (e)  //触摸开始
    recordStartX = e.touches[0].clientX;    //记录触摸的初始位置
    curIndex = e.currentTarget.dataset.index;   //记录当前触摸的盒子下标
    currentOffsetX = this.data.list[curIndex].offsetX;  //记录当前滑块的初始值
    // if(lastIndex != curIndex)
    //     this.data.list[lastIndex].offsetX = 0;
    // 
  
  ,
  touchMove: function (e)  //移动手指,向左移动过程中,事件被不断触发
    let list = this.data.list;
    let endX = e.touches[0].clientX;    //记录移动过程中的位置
    let gapX = recordStartX - endX;     //记录手指滑动的距离
    let result = currentOffsetX - gapX; //记录滑块当前的相对位置
    if (result >= this.data.offsetWidth )  //如果大于下面盒子要显示的距离(因为是相对位置,两个变量都是负数)就改变滑块当前位置
      list[curIndex].offsetX = result;
    
    this.setData(
      list:list
    );
  
  ,
  touchEnd: function (e)  //手指抬起来(触摸结束)
    //lastIndex = curIndex;
    let list = this.data.list;
    let halfOffset = this.data.offsetWidth / 2; 
    if (list[curIndex].offsetX < halfOffset)  //如果滑动距离超过一半就直接滑到终点
        list[curIndex].offsetX = this.data.offsetWidth;
     else 
        list[curIndex].offsetX = 0; //否则就回到起始位置

    
    this.setData(
      list:list
    );
  ,

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () 

  ,

  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function () 

  ,

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () 

  ,

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () 

  ,

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function () 

  ,

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function () 

  ,

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function () 

  
)

这是可以多个盒子同时显示按钮,如果想只能同时显示一个按钮的话,就增加几行代码。

let recordStartX = 0, currentOffsetX = 0, curIndex = 0,lastIndex = 0; //按下初始值,当前滑块初始值,当前滑块下标,上一个滑块下标
Page(

  /**
   * 页面的初始数据
   */
  data: 
    list:[id:1,id:2,id:3],
    offsetWidth:-250, //上面的盒子向左滑动时,下面的盒子要显示出来的宽度,负号是指相对于起始位置向左滑动为负值
  ,

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) 
  ,
  
  touchStart: function (e)  //触摸开始
    recordStartX = e.touches[0].clientX;    //记录触摸的初始位置
    curIndex = e.currentTarget.dataset.index;   //记录当前触摸的盒子下标
    currentOffsetX = this.data.list[curIndex].offsetX;  //记录当前滑块的初始值
    if(lastIndex != curIndex) //如果当前滑块不是上一个滑块,就将上一个滑块归位
        this.data.list[lastIndex].offsetX = 0;
    
  
  ,
  touchMove: function (e)  //移动手指,向左移动过程中,事件被不断触发
    let list = this.data.list;
    let endX = e.touches[0].clientX;    //记录移动过程中的位置
    let gapX = recordStartX - endX;     //记录手指滑动的距离
    let result = currentOffsetX - gapX; //记录滑块当前的相对位置
    if (result >= this.data.offsetWidth )  //如果大于下面盒子要显示的距离(因为是相对位置,两个变量都是负数)就改变滑块当前位置
      list[curIndex].offsetX = result;
    
    this.setData(
      list:list
    );
  
  ,
  touchEnd: function (e)  //手指抬起来(触摸结束)
    lastIndex = curIndex;   //将当前下标的值赋给上一个滑块下标
    let list = this.data.list;
    let halfOffset = this.data.offsetWidth / 2; 
    if (list[curIndex].offsetX < halfOffset)  //如果滑动距离超过一半就直接滑到终点
        list[curIndex].offsetX = this.data.offsetWidth;
     else 
        list[curIndex].offsetX = 0; //否则就回到起始位置

    
    this.setData(
      list:list
    );
  ,

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () 

  ,

  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function () 

  ,

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () 

  ,

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () 

  ,

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function () 

  ,

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function () 

  ,

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function () 

  
)

以上是关于微信小程序购物车 滑动删除效果的主要内容,如果未能解决你的问题,请参考以下文章

ios微信小程序上下滑动效果

微信小程序直播消息滑动

微信小程序开发中如何实现侧边栏的滑动效果

微信小程序 向左滑动显示(删除修改)按钮

微信小程序 向左滑动显示(删除修改)按钮

微信小程序 向左滑动显示(删除修改)按钮