▶動態效果圖◀
▶效果涉及的小程序事件◀
touchstart | 手指觸摸動作開始 | |
touchmove | 手指觸摸後移動 | |
touchend | 手指觸摸動作結束 |
詳細介紹參考文檔:小程序事件詳解
▶WXML◀
<!-- 自定義單選/多選/全選實現刪除功能 -->
<view class="item-box">
<view class="items">
<view wx:for="{{list}}" wx:key="{{index}}" class="item">
<view class='msg' style="{{item.txtStyle}}" bindtouchstart="touchS" bindtouchmove="touchM" bindtouchend="touchE" data-index="{{index}}">
<view class="inner txt">{{item.txt}}</view>
<view class="inner del">
<span class="draw" data-name="{{item.txt}}" bindtap="tryDriver">試駕</span>
<span class="delete" data-index="{{index}}" bindtap="delItem">刪除</span>
</view>
</view>
</view>
</view>
</view>
佈局思路:
每一行數據包括一段文本和兩個操作按鈕,佈局的時候通過right: -120px;設置按鈕不可見,用戶滑動行數據的時候,將整個行數據向左移動,從而顯示出兩個按鈕。
ForEach的集合list中對象item包括兩個屬性
item.txt: 文本內容
item.txtStyle : 定義整行數據向左移動的距離
▶WXSS◀
.item {
position: relative;
border-top: 2rpx solid #eee;
height: 120rpx;
line-height: 120rpx;
overflow: hidden;
}
.inner.txt {
font-family: Monaco;
width: 100%;
z-index: 5;
padding: 0 10rpx;
transition: left 0.2s ease-in-out;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.inner.del {
position: absolute;
width: 260rpx;
height: 148rpx;
top: 1rpx;
right: -120px;
color: #fff;
text-align: center;
line-height: 110rpx;
}
.msg {
position: absolute;
width: 100%;
height: 150rpx;
left: 0;
top: 0;
z-index: 100;
background-color: #fff;
}
.draw {
border-right: 1px solid #fff;
display: inline-block;
width: 120rpx;
height: 115rpx;
background: #d6cdcd;
}
.delete {
display: inline-block;
width: 120rpx;
height: 115rpx;
background: #fd9903;
}
▶ J S ◀
JS中關於滑動效果的三個函數 touchS 、touchM 、touchE
touchS :當觸摸屏上只有一個觸摸點時,設置觸摸起始點水平方向的位置
touchM:當觸摸屏上只有一個觸摸點,計算該點滑動的距離,根據滑動的距離大小設置整行的class屬性txtStyle,從而達到滑動的效果
touchE:當觸摸屏上只有一個觸摸點,計算該點滑動的距離,如果滑動距離大於按鈕長度的1/2則顯示按鈕,否則不顯示
var app = getApp();
Page({
data: {
btnWidth: 260, //按鈕的寬度單位
startX: "", //手指觸摸開始滑動的位置
list: [{ //展示的數據
txtStyle: "", //定義行數據向左偏移原始位置的距離
txt: "試駕車輛_奧迪: 皖B 1567",
},
{
txtStyle: "",
txt: "試駕車輛_寶馬: 陝D 2777",
},
{
txtStyle: "",
txt: "試駕車輛_上汽: 皖A 6666",
}]
},
onLoad: function (options) {
// 頁面初始化
this.initEleWidth();
},
touchS: function (e) {
console.log(e.touches.length);
if (e.touches.length == 1) { //觸摸屏上只有一個觸摸點
this.setData({
//設置觸摸起始點水平方向位置
//clientX:距離頁面可顯示區域(屏幕除去導航條)左上角距離,橫向爲X軸,縱向爲Y軸
startX: e.touches[0].clientX
});
}
},
touchM: function (e) {
if (e.touches.length == 1) { // 一個觸摸點
//手指移動時水平方向位置
var moveX = e.touches[0].clientX;
//手指起始點位置與移動期間的差值
var disX = this.data.startX - moveX;
//按鈕
var btnWidth = this.data.btnWidth;
var txtStyle = "";
if (disX == 0 || disX < 0) {//如果移動距離小於等於0,說明向右滑動,文本層位置不變
txtStyle = "left:0px";
} else if (disX > 0) {//移動距離大於0,文本層left值等於手指移動距離
txtStyle = "left:-" + disX + "px";
if (disX >= btnWidth) {
//控制手指移動距離最大值爲刪除按鈕的寬度
txtStyle = "left:-" + btnWidth + "px";
}
}
//獲取手指觸摸的是哪一項
var index = e.currentTarget.dataset.index;
//設置該項向左偏移的樣式,並消除其他項的偏移樣式
var list = this.data.list;
for (var ix in list) {
ix == index ? list[ix].txtStyle = txtStyle : list[ix].txtStyle = "";
}
//更新列表的狀態
this.setData({
list: list
});
}
},
touchE: function (e) {
if (e.changedTouches.length == 1) { //一個觸摸點
//手指移動結束後水平位置
var endX = e.changedTouches[0].clientX;
//觸摸開始與結束,手指移動的距離
var disX = this.data.startX - endX;
var btnWidth = this.data.btnWidth;
//如果距離小於刪除按鈕的1/2,不顯示刪除按鈕
var txtStyle = disX > btnWidth / 2 ? "left:-" + btnWidth + "px" : "left:0px";
//獲取手指觸摸的是哪一項
var index = e.currentTarget.dataset.index;
//設置偏移的樣式
var list = this.data.list;
list[index].txtStyle = txtStyle;
//更新列表的狀態
this.setData({
list: list
});
}
},
//獲取元素自適應後的實際寬度
getEleWidth: function (w) {
var real = 0;
try {
var res = wx.getSystemInfoSync().windowWidth;
var scale = (750 / 2) / (w / 2);//以寬度750px設計稿做寬度的自適應
real = Math.floor(res / scale);
return real;
} catch (e) {
return false;
// Do something when catch error
}
},
initEleWidth: function () {
var btnWidth = this.getEleWidth(this.data.btnWidth);
this.setData({
btnWidth: btnWidth
});
},
//點擊刪除按鈕事件
delItem: function (e) {
var that = this;
//獲取列表中要刪除項的下標
var index = e.currentTarget.dataset.index;
var list = that.data.list;
wx.showModal({
title: '提示',
content: '是否確認試駕',
success(res) {
if (res.confirm) {
//移除列表中下標爲index的項
list.splice(index, 1);
//更新列表的狀態
that.setData({
list: list
});
}
}
})
},
//點擊試駕
tryDriver: function (e) {
wx.showModal({
title: '提示',
content: '是否確認試駕',
success(res) {
if (res.confirm) {
console.log('開始試駕')
}
}
})
}
})
參考博客:https://www.cnblogs.com/bgwhite/p/9278932.html ,在博主的文章上做了小小的改動