Js实现元素右滑回弹效果(基于Uniapp)

需求说明:

多个view或图片横排显示,可以左右滑动,当滑动到最右侧时实现回弹效果(这里使用匀速动画)。滑动到最右侧显示“查看更多”,达到一定位置显示改完“释放查看”,如果用户释放了则进行相应操作。

如图所示:

代码实现:

view:

<view @touchmove="move" @touchend="moveEnd" @touchstart="moveStart" class="warp" :style="{transform: 'translate('+scl.tranNum+'%, 0px) translateZ(0px)'}">
<view class="list">
<view class="li"></view><view class="li"></view><view class="li"></view><view class="li" id="end"></view>
</view>
<view class="scorll" style="p" v-text="this.scl.sate?'释放查看':'查看更多'"></view>
</view>

js:

<script>
export default {
data() {
return {
scl:{
right:0,//容器距离,判断是否达到最右侧
0,//右滑块的width
tranNum:0,
tx:0,//滑动位置
lastX: 0,
lastY: 0,
inter:null,
sate:false,//状态
}
}
},
methods: {
getDom(dom,callback){
let query = uni.createSelectorQuery().in(this);
query.select(dom).boundingClientRect(res => {
callback(res);
}).exec();
},
move(event){
let currentX = event.changedTouches[0].pageX;
let currentY = event.changedTouches[0].pageY;
let tx = currentX - this.scl.lastX;//向左滑动:tx<0 ,向右滑动tx > 0
let ty = currentY - this.scl.lastY;
if (Math.abs(tx) <= Math.abs(ty)) {//上下方向滑动
return;
}
this.getDom('.list',res=>{
this.scl.right = res.right.toFixed(0);
})
if(this.scl.width==0){
this.getDom('.scorll',res => {
this.scl.width = res.width.toFixed(0);
});
}
this.getDom('#end',res => {
if( this.scl.right == res.right.toFixed(0)){
this.scl.tx = this.scl.tx + tx;
let scale= -(this.scl.right / this.scl.width)*100;//计算占比
this.scl.tx = this.scl.tx<scale ? scale : this.scl.tx;
if(this.scl.tx<0){
if( -(scale -this.scl.tx) <90){//这里的90按需求定
this.scl.sate = true;
}else{
this.scl.sate = false;
}
this.scl.tranNum=this.scl.tx*0.1;
}
}
});
//将当前坐标进行保存以进行下一次计算
this.scl.lastX = currentX;
this.scl.lastY = currentY;
},
moveEnd(event){
if(this.scl.tx<=0){
this.scl.inter=setInterval(()=>{
this.scl.tx=this.scl.tx+10;
this.scl.tx = this.scl.tx>=0 ? 0 : this.scl.tx;
this.scl.tranNum=this.scl.tx*0.1;
if(this.scl.tx==0){
clearInterval(this.scl.inter);
}
},10);
}else{
this.scl.tx=0;
this.scl.inter && clearInterval(this.scl.inter);
}
if(this.scl.sate){//执行操作
console.log("执行操作!")
}
},
moveStart(event){
this.scl.lastX = event.changedTouches[0].pageX;
this.scl.lastY = event.changedTouches[0].pageY;
},
}
}
</script>

less:

<style lang="less">
.warp{
position: relative;
height: 200px;
100%;
white-space: nowrap;
-webkit-overflow-scrolling:touch;
transform: translate(0px, 0px) translateZ(0px);/*使用该属性来实现*/
.list{
height: 100%;
100%;
position: relative;
font-size: 0;
overflow: auto;
.li{
display: inline-block;
vertical-align: middle;
height: 100%;
400rpx;
margin-right: 30rpx;
background: #f1f2f3;
}
&>view:last-of-type{
margin-right: 0rpx;
}
}
.scorll{
display: inline-block;
vertical-align: middle;
font-size: 24rpx;
color: #999;
200rpx;
text-align: center;
position: absolute;
top: 0;
right: -200rpx;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
}
</style>

https://www.98891.com/article-2-1.html

总结:

1、主要使用css中transform: translate(0px, 0px) translateZ(0px);的属性来实现。transform 属性向元素应用 2D 或 3D 转换,该属性允许我们对元素进行旋转、缩放、移动或倾斜。

2、事件使用到:touchmove,touchend,touchstart。

3、uniapp不支持直接获取dom相应的属性,需要借助uni.createSelectorQuery()方法来实现。

4、代码比较粗糙,临时写的,许多细节未处理,后续再优化吧。

原文地址:https://www.cnblogs.com/xiaonian8/p/14928101.html