vue2工程
长按触发
<template>
<div>
<button class="floating-btn" @touchstart="startLongPress" @touchmove="stopLongPress" @touchend="stopLongPress">
<van-icon name="aim" size="40" />
</button>
</div>
</template>
<script>
export default {
name: 'App',
data() {
return {
longPressTimeout: null,
pressDuration: 1000, // 设置长按时间阈值为 1000 毫秒(1秒)
isPressing: false
};
},
mounted() {
},
methods: {
startLongPress() {
console.log("______1111");
// 清除任何已有的长按计时器(防止连续点击)
if (this.longPressTimeout) {
clearTimeout(this.longPressTimeout);
}
// 设定计时器
this.longPressTimeout = setTimeout(() => {
this.isPressing = true;
this.onLongPress();
}, this.pressDuration);
},
stopLongPress() {
console.log("______2222");
// 如果长按时间小于设定阈值,取消触发长按事件
if (this.longPressTimeout) {
clearTimeout(this.longPressTimeout);
this.longPressTimeout = null;
}
// 如果按下时间不到阈值,说明不是长按
if (this.isPressing) {
this.isPressing = false;
}
},
onLongPress() {
console.log("______333");
// 处理长按事件
alert("长按触发!");
}
}
}
</script>
<style lang="scss">
.floating-btn {
width: 50px;
height: 50px;
position: fixed;
bottom: 130px;
right: 20px;
background-color: transparent;
color: white;
border: none;
border-radius: 50%;
cursor: pointer;
box-shadow: 0px 8px 16px rgba(0, 0, 0, 0.2);
z-index: 9999999;
background-color: #7289e6;
display: flex;
align-items: center;
justify-content: center;
}
// .floating-btn:hover {
// background-color: #ff80b5;
// }
</style>
长按松开触发,效果如下
<template>
<div :class="[{ 'voiceview': voicestart }]">
<div class="speak-content">
<Typing v-if="voicestart" style="z-index: 99999;"/>
</div>
<div class="speak-btn">
<div class="tip" v-if="voicestart && !isOverTarget">松开 发送</div>
<div class='btn' @touchstart="startLongPress" @touchend="stopLongPress" @touchmove="touchmove">
按住说话
</div>
</div>
<div class="delete-btn" v-if="voicestart">
<div class="tip" v-if="isOverTarget">松开 取消发送</div>
<div class='btn' ref="targetArea">
拉到这里松开取消
</div>
</div>
</div>
</template>
<script>
import Typing from './Typing.vue';
export default {
name: 'App',
data() {
return {
voicestart: false,
longPressTimer: null,
isOverTarget: false, // 判断是否进入目标区域
startX: 0, // 记录触摸开始时的X坐标
startY: 0, // 记录触摸开始时的Y坐标
Typingshow:false
};
},
components: {
Typing
},
mounted() {
},
methods: {
startLongPress(event) {
this.longPressTimer = setTimeout(() => {
this.voicestart = true;
const touch = event.touches[0]; // 获取触摸点
this.startX = touch.clientX;
this.startY = touch.clientY;
this.isOverTarget = false; // 重置进入目标区域的状态
setTimeout(() => {
this.Typingshow=true;
}, 1500);
}, 500);
},
stopLongPress() {
console.log("发送语音或者取消语音");
if (this.isOverTarget) {
console.log("取消语音");
this.Typingshow=false;
} else {
console.log("发送语音");
}
this.isOverTarget = false; // 触摸结束时清除状态
clearTimeout(this.longPressTimer);
this.voicestart = false;
},
touchmove(event) {
const touch = event.touches[0]; // 获取触摸点
const touchX = touch.clientX;
const touchY = touch.clientY;
// 获取目标元素的位置信息
const targetRect = this.$refs.targetArea.getBoundingClientRect();
// 判断触摸点是否在目标区域内
const isInsideTarget =
touchX >= targetRect.left &&
touchX <= targetRect.right &&
touchY >= targetRect.top &&
touchY <= targetRect.bottom;
this.isOverTarget = isInsideTarget;
}
}
}
</script>
<style lang="scss">
.speak-btn {
position: fixed;
bottom: 130px;
right: 20px;
z-index: 9999;
display: flex;
flex-direction: column;
align-items: end;
.tip {
color: white;
font-size: 16px;
}
.btn {
margin-top: 20px;
width: 50px;
height: 50px;
background-color: transparent;
color: white;
border: none;
border-radius: 50%;
cursor: pointer;
box-shadow: 0px 8px 16px rgba(0, 0, 0, 0.2);
background-color: #7289e6;
display: flex;
align-items: center;
justify-content: center;
}
}
.delete-btn {
position: fixed;
bottom: 130px;
left: 20px;
z-index: 9999;
display: flex;
flex-direction: column;
align-items: start;
.tip {
color: white;
font-size: 16px;
}
.btn {
font-size: 16px;
margin-top: 20px;
width: 50px;
height: 50px;
background-color: transparent;
color: white;
border: none;
border-radius: 50%;
cursor: pointer;
box-shadow: 0px 8px 16px rgba(0, 0, 0, 0.2);
background-color: #e34d4d;
display: flex;
align-items: center;
justify-content: center;
}
}
.speak-content{
position: fixed;
top: 50%;
transform: translateY(-50%);
padding: 20px;
margin-top: -120px;
}
// .speak-btn:hover {
// background-color: #ff80b5;
// }
.voiceview {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.85);
display: flex;
// justify-content: center;
align-items: center;
flex-direction: column;
z-index: 9999;
}
</style>