微信小程序学习用demo推荐:列表项左滑删除效果

要实现的效果:
1,当向左滑动时,item跟随手指像左移动,同时右侧出现两个可点击的按钮
2,当滑动距离大于按钮宽度一半松开手指时,item自动滑动到左侧显示出按钮,小于一半时item自动回到原来的位置,隐藏按钮。

思路:

1,首先页面每个item分为上下两层,上面一层放置正常内容,下面一层放置左滑显示出的按钮,这个可以使用z-index来实现分层。
2,item上层使用绝对定位,我们操纵 left 属性的值来实现像左移动。
3,我们通过微信小程序api提供的touch对象和3个有关手指触摸的函数(touchstart,touchmove,touchend)来实现item随手指移动。

微信小程序学习用demo推荐:列表项左滑删除效果

小程序api-touch对象

微信小程序学习用demo推荐:列表项左滑删除效果

实现思路:
1、每一个列表项由两个层组成,文本层与按钮层;
2、触摸滑动时计算手指移动距离,文本层跟随手指移动;
3、手指移动距离大于按钮宽度一半时,显示按钮,反之,不显示;
4、缓动动画用css3属性transition控制;transition: left 0.2s ease-in-out;
微信小程序学习用demo推荐:列表项左滑删除效果 
微信小程序学习用demo推荐:列表项左滑删除效果 
代码:
代码比较简单,详细实现看注释,就直接贴代码了。
index.wxml

[HTML] 纯文本查看 复制代码

?

01

02

03

04

05

06

07

08

09

10

<viewclass="item-box">

  <viewclass="items">

    <viewwx:for="{{list}}" wx:key="{{index}}" class="item">

     

      <viewbindtouchstart="touchS"bindtouchmove="touchM"bindtouchend="touchE"data-index="{{index}}"style="{{item.txtStyle}}"class="inner txt">

      <imageclass="item-icon"mode="widthFix"src="{{item.icon}}"></image>{{item.txt}}</view>

      <viewdata-index="{{index}}"bindtap  = "delItem"class="inner del">删除</view>

    </view>

  </view>

</view>



index.wxss

[CSS] 纯文本查看 复制代码

?

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

/* pages/leftSwiperDel/index.wxss */

view{

    box-sizing: border-box;

}

.item-box{

    width700rpx;

    margin0auto;

    padding:40rpx 0;

}

.items{

    width100%;

}

.item{

    positionrelative;

    border-top2rpx solid#eee;

    height120rpx;

    line-height120rpx;

    overflowhidden;

     

}

.item:last-child{

    border-bottom2rpx solid#eee;

}

.inner{

    positionabsolute;

    top:0;

}

.inner.txt{

    background-color#fff;

    width100%;

    z-index5;

    padding:010rpx;

    transition: left0.2s ease-in-out;

    white-space:nowrap;

    overflow:hidden;

    text-overflow:ellipsis;

}

.inner.del{

    background-color#e64340;

    width180rpx;text-aligncenter;

    z-index4;

    right0;

    color#fff

}

.item-icon{

    width64rpx;

    vertical-alignmiddle;

    margin-right16rpx

}


index.js

[JavaScript] 纯文本查看 复制代码

?

001

002

003

004

005

006

007

008

009

010

011

012

013

014

015

016

017

018

019

020

021

022

023

024

025

026

027

028

029

030

031

032

033

034

035

036

037

038

039

040

041

042

043

044

045

046

047

048

049

050

051

052

053

054

055

056

057

058

059

060

061

062

063

064

065

066

067

068

069

070

071

072

073

074

075

076

077

078

079

080

081

082

083

084

085

086

087

088

089

090

091

092

093

094

095

096

097

098

099

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

// pages/leftSwiperDel/index.js

Page({

  data:{

    delBtnWidth:180//删除按钮宽度单位(rpx)

  },

  onLoad:function(options){

    // 页面初始化 options为页面跳转所带来的参数

    this.initEleWidth();

    this.tempData();

  },

  onReady:function(){

    // 页面渲染完成

  },

  onShow:function(){

    // 页面显示

  },

  onHide:function(){

    // 页面隐藏

  },

  onUnload:function(){

    // 页面关闭

  },

  touchS:function(e){

    if(e.touches.length==1){

      this.setData({

        //设置触摸起始点水平方向位置

        startX:e.touches[0].clientX

      });

    }

  },

  touchM:function(e){

    if(e.touches.length==1){

      //手指移动时水平方向位置

      varmoveX = e.touches[0].clientX;

      //手指起始点位置与移动期间的差值

      vardisX = this.data.startX - moveX;

      vardelBtnWidth = this.data.delBtnWidth;

      vartxtStyle = "";

      if(disX == 0 || disX < 0){//如果移动距离小于等于0,文本层位置不变

        txtStyle = "left:0px";

      }elseif(disX > 0 ){//移动距离大于0,文本层left值等于手指移动距离

        txtStyle = "left:-"+disX+"px";

        if(disX>=delBtnWidth){

          //控制手指移动距离最大值为删除按钮的宽度

          txtStyle = "left:-"+delBtnWidth+"px";

        }

      }

      //获取手指触摸的是哪一项

      varindex = e.target.dataset.index;

      varlist = this.data.list;

      list[index].txtStyle = txtStyle;

      //更新列表的状态

      this.setData({

        list:list

      });

    }

  },

 

  touchE:function(e){

    if(e.changedTouches.length==1){

      //手指移动结束后水平位置

      varendX = e.changedTouches[0].clientX;

      //触摸开始与结束,手指移动的距离

      vardisX = this.data.startX - endX;

      vardelBtnWidth = this.data.delBtnWidth;

      //如果距离小于删除按钮的1/2,不显示删除按钮

      vartxtStyle = disX > delBtnWidth/2 ? "left:-"+delBtnWidth+"px":"left:0px";

      //获取手指触摸的是哪一项

      varindex = e.target.dataset.index;

      varlist = this.data.list;

      list[index].txtStyle = txtStyle;

      //更新列表的状态

      this.setData({

        list:list

      });

    }

  },

  //获取元素自适应后的实际宽度

  getEleWidth:function(w){

    varreal = 0;

    try{

      varres = wx.getSystemInfoSync().windowWidth;

      varscale = (750/2)/(w/2);//以宽度750px设计稿做宽度的自适应

      // console.log(scale);

      real = Math.floor(res/scale);

      returnreal;

    catch(e) {

      returnfalse;

     // Do something when catch error

    }

  },

  initEleWidth:function(){

    vardelBtnWidth = this.getEleWidth(this.data.delBtnWidth);

    this.setData({

      delBtnWidth:delBtnWidth

    });

  },

  //点击删除按钮事件

  delItem:function(e){

    //获取列表中要删除项的下标

    varindex = e.target.dataset.index;

    varlist = this.data.list;

    //移除列表中下标为index的项

    list.splice(index,1);

    //更新列表的状态

    this.setData({

      list:list

    });

  },

  //测试临时数据

  tempData:function(){

    varlist = [

        {

          txtStyle:"",

          icon:"/images/icon0.png",

          txt:"向左滑动可以删除"

        },

        {

          txtStyle:"",

          icon:"/images/icon6.png",

          txt:"微信小程序|联盟(wxapp-union.com)"

        },

        {

          txtStyle:"",

          icon:"/images/icon1.png",

          txt:"圣诞老人是爸爸,顺着烟囱往下爬,礼物塞满圣诞袜,平安糖果一大把"

        },

        {

          txtStyle:"",

          icon:"/images/icon2.png",

          txt:"圣诞到来,元旦还会远吗?在圣诞这个日子里"

        },

        {

          txtStyle:"",

          icon:"/images/icon3.png",

          txt:"圣诞节(Christmas或Cristo Messa ),译名为“基督弥撒”。"

        },

        {

          txtStyle:"",

          icon:"/images/icon4.png",

          txt:"一年一度的圣诞节即将到来,姑娘们也纷纷开始跑趴了吧!"

        },

        {

          txtStyle:"",

          icon:"/images/icon5.png",

          txt:"圣诞节(Christmas或Cristo Messa ),译名为“基督弥撒”。"

        },

        {

          txtStyle:"",

          icon:"/images/icon2.png",

          txt:"你的圣诞节礼物准备好了吗?"

        },

        {

          txtStyle:"",

          icon:"/images/icon3.png",

          txt:"一年一度的圣诞节即将到来,姑娘们也纷纷开始跑趴了吧!"

        },

        {

          txtStyle:"",

          icon:"/images/icon4.png",

          txt:"圣诞到来,元旦还会远吗?"

        },

        {

          txtStyle:"",

          icon:"/images/icon5.png",

          txt:"记下这一刻的心情"

        },

 

      ];

     

    this.setData({

      list:list

    });

  }

   

})


测试:
测试安卓系统5.1能正常使用
测试苹果ios系统10.2能正常使用
问题:
左滑动时会默认触发整个页面的弹动效果,如果使用catch绑定touch事件可以阻止默认弹动,但是列表会无法下拉。暂时没有想到好的办法,有知道怎么解决的大神烦请告知。有任何问题请留言微信小程序学习用demo推荐:列表项左滑删除效果