Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

微信小程序中实现滑动删除效果 #121

Open
wlin00 opened this issue Jan 12, 2021 · 0 comments
Open

微信小程序中实现滑动删除效果 #121

wlin00 opened this issue Jan 12, 2021 · 0 comments

Comments

@wlin00
Copy link
Collaborator

wlin00 commented Jan 12, 2021

在微信小程序开发中,经常会遇到在一个列表页中,给列表元素添加滑动出现删除按钮的需求。
滑动删除的实现方法:
1、由小程序触控事件bindtouchstart监听用户触摸点击的初始坐标
2、由小程序bindtouchmove事件来获取触摸滑动的结束坐标
3、通过比较两点之间的角度、两点的横坐标差值,判断当前用户是左滑动还是右滑动。

Demo如下:
wxml:

<view class='test'>
  <view 
    data-index="{{index}}" 
    bindtouchstart="handleClick" 
    bindtouchmove="handleMove" 
    class="test-item {{item.isTouchMove ? 'active' : ''}}" 
    wx:for="{{list}}" 
    wx:for-item="item"
    wx:key="{{index}}">
      <view class='test-item__left'>{{item.name}}</view>
      <view class='test-item__right'>删除</view>
  </view>
</view>

js

Page({
  /**
   * 页面的初始数据
   */
  data: {
    list: [ // 列表数据
      { id: '333', name:'testA' },
      { id: '444', name: 'testB'}
    ], 
    startX: 0,// 用户点击触摸的起始横坐标
    startY: 0, // 用户点击触摸的起始纵坐标
  },

  // 计算两点之间的角度
  getAngle: function(start, end) {
    let x = end.X - start.X;
    let y = end.Y - start.Y;
    return (360 * Math.atan(y / x)) / (Math.PI * 2)
  },

  // 触摸面板的回调
  handleClick: function(e) {
    // 关闭列表中处于激活状态的按钮
    const list = this.data.list
    list.forEach(e => {
      if (e.isTouchMove) {
        e.isTouchMove = false
      }
    })

    this.setData({
      startX: e.changedTouches[0].clientX,
      startY: e.changedTouches[0].clientY,
      list: list,
    })
  },

  // 滑动面板的回调
  handleMove: function(e) {
    let self = this,
      index = e.currentTarget.dataset.index, //当前索引
      startX = self.data.startX, //开始X坐标
      startY = self.data.startY, //开始Y坐标
      endX = e.changedTouches[0].clientX, //滑动变化坐标
      endY = e.changedTouches[0].clientY, //滑动变化坐标
      //获取滑动角度
      angle = self.getAngle(
        { X: startX, Y: startY },
        { X: endX, Y: endY }
      );

      // 将其他按钮置为关闭状态
      const list = self.data.list
      list.forEach((v, i) => {
        v.isTouchMove = false;
        //滑动角度超过30度角视为无效滑动
        if (Math.abs(angle) > 30) return;
        if (i == index) {
          v.isTouchMove = endX < startX
        }
      });

      //更新数据
      self.setData({
        list: list
      });
    },
})

wxss:

.test{
  width: 100%;
  height: 100%;
  background: #fff;
}

.test-item{
  width: 100%;
  display: flex;
  flex-direction: row;
  margin-bottom: 20rpx;
}

.test-item__left{
  width: 100%;
  height: 110rpx;
  background: aliceblue;
  margin-right: 0;
  transform: translateX(180rpx);
  margin-left: -180rpx;
  padding: 10px;
  transition: 0.3s linear;
}

.test-item__right{
  width: 180rpx;
  display: flex;
  align-items: center;
  justify-content: center;
  transform: translateX(180rpx);
  background: red;
  color: #fff;
  transition: 0.3s linear;
}

.active .test-item__left,
.active .test-item__right{
  transform: translateX(0);
}

查看在线实例

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant