提交 8d8864bb 编写于 作者: DCloud-yyl's avatar DCloud-yyl

优化关闭半屏弹窗可能出现抖一下的问题

上级 36f7ad31
<template> <template>
<view id="page" class="page"> <view id="page" class="page">
<text style="margin: 10px">半屏弹窗效果是通过监听TouchEvent实现,当半屏窗口移动时禁用scroll-view的滚动,避免两者的冲突。</text> <text
style="margin: 10px">半屏弹窗,演示了弹出层内scroll-view滚动到顶时由滚变拖。本效果是通过监听TouchEvent实现,当半屏窗口移动时禁用scroll-view的滚动,避免两者的冲突。</text>
<button class="bottomButton" @click="switchHalfScreen(true)">打开弹窗</button> <button class="bottomButton" @click="switchHalfScreen(true)">打开弹窗</button>
<view id="halfScreen" class="halfScreen" @touchstart="onHalfTouchStart" @touchmove="onHalfTouchMove" @touchend="onHalfTouchEnd"> <view id="halfScreen" class="halfScreen" @touchstart="onHalfTouchStart" @touchmove="onHalfTouchMove"
<view class="halfTitle" >半屏弹窗标题</view> @touchend="onHalfTouchEnd">
<scroll-view id="halfScroll" class="halfScroll" @scroll="onScroll" rebound="true"> <view class="halfTitle">半屏弹窗标题</view>
<scroll-view id="halfScroll" class="halfScroll" rebound="true">
<view v-for="(item,index) in list" :key="index" class="item"> <view v-for="(item,index) in list" :key="index" class="item">
half screen content-{{item}} half screen content-{{item}}
</view> </view>
...@@ -17,7 +19,7 @@ ...@@ -17,7 +19,7 @@
export default { export default {
data() { data() {
return { return {
list: ['1','2','3','4','5','6','7','8','9','10','11','12','13','14','15'], list: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15'],
totalHeight: 0, //总高度 totalHeight: 0, //总高度
halfMove: false, //是否Move,响应TouchMove halfMove: false, //是否Move,响应TouchMove
halfScreenY: 0, //响应TouchMove的起始点Y坐标 halfScreenY: 0, //响应TouchMove的起始点Y坐标
...@@ -31,70 +33,59 @@ ...@@ -31,70 +33,59 @@
} }
}, },
methods: { methods: {
onHalfTouchStart(_:TouchEvent) { onHalfTouchStart(_ : TouchEvent) {
this.halfNode?.style?.setProperty('transitionDuration', 0); this.halfNode?.style?.setProperty('transitionDuration', 0);
//console.log('Title TouchStart: ', e);
}, },
onHalfTouchMove(e:TouchEvent) { onHalfTouchMove(e : TouchEvent) {
if(this.bAnimation){//容错处理 if (this.bAnimation) {//容错处理
return; return;
} }
let top:number = this.scrollNode?.scrollTop??0; let top : number = this.scrollNode?.scrollTop ?? 0;
let p = e.touches[0]; let p = e.touches[0];
this.lastY2 = this.lastY; this.lastY2 = this.lastY;
this.lastY = p.screenY; this.lastY = p.screenY;
if(top <= 0.01 || this.halfMove){ if (top <= 0.01 || this.halfMove) {
if(this.halfScreenY == 0){ if (this.halfScreenY == 0) {
this.halfScreenY = p.screenY; this.halfScreenY = p.screenY;
} }
let offset = p.screenY-this.halfScreenY; let offset = p.screenY - this.halfScreenY;
if(offset > 0){//向下滚动 if (offset > 0) {//向下滚动
this.halfMove = true; this.halfMove = true;
this.scrollNode?.setAttribute('scroll-y', 'false'); this.scrollNode?.setAttribute('scroll-y', 'false');
this.halfNode?.style?.setProperty('transform','translateY('+offset+'px)'); this.halfNode?.style?.setProperty('transform', 'translateY(' + offset.toFixed(2) + 'px)');
if(offset==0){
console.log('translateY(0px)', this.halfOffset)
}
this.halfOffset = offset; this.halfOffset = offset;
}else if(this.halfOffset>0){//向上滚动 } else if (this.halfOffset > 0) {//向上滚动
offset = this.halfScreenY-p.screenY; offset = this.halfScreenY - p.screenY;
if(offset>this.halfOffset){ if (offset > this.halfOffset) {
offset = 0; offset = 0;
this.halfMove = false; this.halfMove = false;
this.scrollNode?.setAttribute('scroll-y', 'true'); this.scrollNode?.setAttribute('scroll-y', 'true');
} }
this.halfNode?.style?.setProperty('transform','translateY('+offset+'px)'); this.halfNode?.style?.setProperty('transform', 'translateY(' + offset.toFixed(2) + 'px)');
if(offset==0){
console.log('translateY(0px)', this.halfOffset)
}
this.halfOffset = offset; this.halfOffset = offset;
} }
} }
//console.log('TouchMove', e.target);
}, },
onHalfTouchEnd(_:TouchEvent) { onHalfTouchEnd(_ : TouchEvent) {
this.halfScreenY = 0; this.halfScreenY = 0;
if(this.bAnimation){//容错处理 if (this.bAnimation) {//容错处理
return; return;
} }
let top:number = this.scrollNode?.scrollTop??0; let top : number = this.scrollNode?.scrollTop ?? 0;
let bHide = (this.halfHeight-this.halfOffset)<this.halfHeight/4; let bHide = (this.halfHeight - this.halfOffset) < this.halfHeight / 4;
if(bHide){ if (bHide) {
bHide = this.lastY2>0&&this.lastY2<=this.lastY; bHide = this.lastY2 > 0 && this.lastY2 <= this.lastY;
}else if(top <= 0.01){ } else if (top <= 0.01) {
bHide = (this.lastY-this.lastY2)>3; //向下滑动计算加速度判断是否关闭,简单处理未考虑时间 bHide = (this.lastY - this.lastY2) > 3; //向下滑动计算加速度判断是否关闭,简单处理未考虑时间
} }
if(bHide){ if (bHide) {
this.switchHalfScreen(false); this.switchHalfScreen(false);
}else if(this.halfOffset>0){ } else if (this.halfOffset > 0) {
this.resumeHalfScreen(); this.resumeHalfScreen();
} }
}, },
onScroll(_: ScrollEvent) { switchHalfScreen(show : boolean) {
//console.log('onScroll: ', e); if (show && ('visible' == this.halfNode?.style?.getPropertyValue('visibility'))) {//容错处理
},
switchHalfScreen(show:boolean) {
if(show&&('visible'==this.halfNode?.style?.getPropertyValue('visibility'))){//容错处理
console.log('qucik click button!!!'); console.log('qucik click button!!!');
return; return;
} }
...@@ -104,40 +95,41 @@ ...@@ -104,40 +95,41 @@
this.halfOffset = 0; this.halfOffset = 0;
let top = this.totalHeight; let top = this.totalHeight;
let time = 300; let time = 300;
if(show){ if (show) {
top = this.totalHeight*30/100; //计算显示的位置 top = this.totalHeight * 30 / 100; //计算显示的位置
this.halfNode?.style?.setProperty('visibility','visible'); this.halfNode?.style?.setProperty('visibility', 'visible');
this.halfNode?.style?.setProperty('transitionTimingFunction','ease-in-out'); this.halfNode?.style?.setProperty('transitionTimingFunction', 'ease-in-out');
}else{ } else {
this.halfNode?.style?.setProperty('transitionTimingFunction','linear'); this.halfNode?.style?.setProperty('transitionTimingFunction', 'linear');
time *= (this.halfHeight/this.totalHeight); //计算关闭动画时间 time *= (this.halfHeight / this.totalHeight); //计算关闭动画时间
} }
this.halfNode?.style?.setProperty('transitionDuration', time.toFixed(0)); this.halfNode?.style?.setProperty('transitionDuration', time.toFixed(0));
this.halfNode?.style?.setProperty('transitionProperty','top'); this.halfNode?.style?.setProperty('transitionProperty', 'top');
this.halfNode?.style?.setProperty('top', top.toFixed(2)); this.halfNode?.style?.setProperty('top', top.toFixed(2));
setTimeout(()=>{ setTimeout(() => {
if(!show){ if (!show) {
this.halfNode?.style?.setProperty('visibility','hidden'); this.halfNode?.style?.setProperty('visibility', 'hidden');
this.halfNode?.style?.setProperty('transitionDuration', 0); this.halfNode?.style?.setProperty('transitionDuration', 0);
this.halfNode?.style?.setProperty('transform',''); this.halfNode?.style?.setProperty('transform', '');
} }
this.halfNode?.style?.setProperty('transitionProperty',''); this.halfNode?.style?.setProperty('transitionProperty', '');
this.bAnimation = false; this.bAnimation = false;
}, time) }, time)
this.bAnimation = true; this.bAnimation = true;
}, },
resumeHalfScreen() { resumeHalfScreen() {
let time = 300;//(500*this.halfOffset/this.halfHeight).toFixed(0); //回弹动画时间 let time = 300;//(500*this.halfOffset/this.halfHeight).toFixed(0); //回弹动画时间
this.halfNode?.style?.setProperty('transitionDuration',time.toFixed(0)); this.halfNode?.style?.setProperty('transitionDuration', time.toFixed(0));
this.halfNode?.style?.setProperty('transitionTimingFunction','ease-in-out'); this.halfNode?.style?.setProperty('transitionTimingFunction', 'ease-in-out');
this.halfNode?.style?.setProperty('transitionProperty','transform'); this.halfNode?.style?.setProperty('transitionProperty', 'transform');
this.halfNode?.style?.setProperty('transform','translateY(0px)'); this.halfNode?.style?.setProperty('transform', 'translateY(0px)');
this.halfMove = false; this.halfMove = false;
this.scrollNode?.setAttribute('scroll-y', 'true'); this.scrollNode?.setAttribute('scroll-y', 'true');
this.halfScreenY = 0; this.halfScreenY = 0;
this.halfOffset = 0; this.halfOffset = 0;
setTimeout(()=>{ setTimeout(() => {
this.bAnimation = false; this.bAnimation = false;
this.halfNode?.style?.setProperty('transitionProperty', '');
}, time) }, time)
this.bAnimation = true; this.bAnimation = true;
} }
...@@ -147,49 +139,55 @@ ...@@ -147,49 +139,55 @@
this.scrollNode = uni.getElementById('halfScroll'); this.scrollNode = uni.getElementById('halfScroll');
this.halfHeight = this.halfNode!.getBoundingClientRect().height; this.halfHeight = this.halfNode!.getBoundingClientRect().height;
this.totalHeight = uni.getElementById('page')?.getBoundingClientRect()?.height??0;//uni.getWindowInfo().windowHeight; this.totalHeight = uni.getElementById('page')?.getBoundingClientRect()?.height ?? 0;//uni.getWindowInfo().windowHeight
this.halfNode?.style?.setProperty('top', this.totalHeight.toFixed(2)); this.halfNode?.style?.setProperty('top', this.totalHeight.toFixed(2));
}, },
onResize() { onResize() {
this.halfHeight = this.halfNode?.getBoundingClientRect()?.height??0; this.halfHeight = this.halfNode?.getBoundingClientRect()?.height ?? 0;
this.totalHeight = uni.getElementById('page')?.getBoundingClientRect()?.height??0; this.totalHeight = uni.getWindowInfo().windowHeight;
this.halfNode?.style?.setProperty('top', this.totalHeight.toFixed(2)); this.halfNode?.style?.setProperty('top', this.totalHeight.toFixed(2));
this.halfNode?.style?.setProperty('visibility','hidden'); this.halfNode?.style?.setProperty('visibility', 'hidden');
} }
} }
</script> </script>
<style> <style>
.page { .page {
flex: 1; flex: 1;
background-color: darkgrey; background-color: darkgrey;
} }
.bottomButton {
.bottomButton {
position: absolute; position: absolute;
width: 100%; width: 100%;
bottom: 0px; bottom: 0px;
} }
.halfScreen {
.halfScreen {
position: absolute; position: absolute;
top: 100%; top: 100%;
width: 100%; width: 100%;
height: 70%; height: 70%;
transition-timing-function: ease-in-out; /*ease ease-in ease-out ease-in-out linear step-start step-end*/ transition-timing-function: ease-in-out;
/*ease ease-in ease-out ease-in-out linear step-start step-end*/
transition-property: top; transition-property: top;
transition-duration: 0; transition-duration: 0;
visibility: hidden; visibility: hidden;
} }
.halfTitle {
.halfTitle {
align-items: center; align-items: center;
justify-content: center; justify-content: center;
height: 48px; height: 48px;
background-color: ghostwhite; background-color: ghostwhite;
border-radius: 10px 10px 0 0; border-radius: 10px 10px 0 0;
} }
.halfScroll {
.halfScroll {
background-color: white; background-color: white;
} }
.item {
.item {
height: 100px; height: 100px;
} }
</style> </style>
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册