移动端按住说话样式
下面是最终效果,手指移出指定区域就改为取消状态,松开手指就取消,手指没有移出指定区域,状态为录音中,松开手指为结束录音状态

下面是代码
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>语音交互样式</title> <style> body { font-family: Arial, sans-serif; display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; background-color: #f5f5f5; } .voice-container { position: relative; width: 200px; height: 200px; } /* 语音交互按钮 */ .voice-btn { position: absolute; bottom: 20px; left: 50%; transform: translateX(-50%); width: 80px; height: 80px; background-color: #4CAF50; border-radius: 50%; display: flex; justify-content: center; align-items: center; color: white; font-size: 20px; cursor: pointer; transition: background-color 0.3s; } .voice-btn:active { background-color: #388E3C; } /* 正在语音识别的状态 */ .voice-recognizing { position: absolute; bottom: 0; left: 50%; transform: translateX(-50%); width: 100%; height: 100px; background-color: rgba(0, 0, 0, 0.2); border-radius: 20px 20px 0 0; display: flex; justify-content: center; align-items: center; color: white; font-size: 16px; display: none; /* 默认隐藏 */ transition: background-color 0.3s; } /* 预取消状态:当手指移出语音识别区域时,改变样式 */ .voice-recognizing.canceling { background-color: rgba(255, 0, 0, 0.5); /* 改为红色表示预取消 */ } /* 取消区域:顶部区域用于取消语音识别 */ .cancel-area { position: absolute; top: 0; left: 50%; transform: translateX(-50%); width: 100%; height: 30px; background-color: rgba(255, 0, 0, 0.8); /* 红色背景 */ color: white; text-align: center; line-height: 30px; font-size: 14px; display: none; /* 默认隐藏 */ cursor: pointer; z-index: 1; } /* 取消区域显示 */ .cancel-area.show { display: block; } /* 取消区域 hover 样式 */ .cancel-area:hover { background-color: rgba(255, 0, 0, 1); } </style> </head> <body> <div class="voice-container"> <!-- 语音交互按钮 --> <div class="voice-btn" id="voiceBtn"> 🎤 </div> <!-- 正在语音识别 --> <div class="voice-recognizing" id="voiceRecognizing"> 正在识别... </div> <!-- 取消区域 --> <div class="cancel-area" id="cancelArea"> 松开手指取消语音识别 </div> </div> <script> const voiceBtn = document.getElementById('voiceBtn'); const voiceRecognizing = document.getElementById('voiceRecognizing'); const cancelArea = document.getElementById('cancelArea'); let isRecognizing = false; // 标识当前是否正在识别 let isTouching = false; // 标识是否有触摸事件正在进行 let touchStartY = 0; // 记录触摸开始的位置 let isCanceling = false; // 标识是否进入预取消状态 // 按下按钮开始语音识别 voiceBtn.addEventListener('mousedown', startRecognition); voiceBtn.addEventListener('touchstart', startRecognition); function startRecognition(e) { e.preventDefault(); // 阻止默认事件,避免页面滚动等 isRecognizing = true; voiceRecognizing.style.display = 'flex'; // 显示正在语音识别的状态 cancelArea.classList.add('show'); // 显示取消区域 isTouching = true; isCanceling = false; // 初始状态不是预取消 // 记录触摸开始的位置,用于判断手指滑动方向 if (e.type === 'touchstart') { touchStartY = e.touches[0].clientY; } // 禁止页面滚动 document.body.style.overflow = 'hidden'; } // 松开按钮结束语音识别 voiceBtn.addEventListener('mouseup', stopRecognition); voiceBtn.addEventListener('touchend', stopRecognition); function stopRecognition(e) { if (isRecognizing && isCanceling) { // 如果处于预取消状态,取消语音识别 cancelRecognition(); } else if (isRecognizing) { // 如果没有进入取消区域,正常结束语音识别 finishRecognition(); } isTouching = false; isCanceling = false; // 恢复页面滚动 document.body.style.overflow = 'auto'; } // 取消语音识别 function cancelRecognition() { isRecognizing = false; voiceRecognizing.style.display = 'none'; // 隐藏正在识别状态 cancelArea.classList.remove('show'); // 隐藏取消区域 voiceRecognizing.classList.remove('canceling'); // 清除预取消状态样式 alert('语音识别已取消'); } // 完成语音识别 function finishRecognition() { isRecognizing = false; voiceRecognizing.style.display = 'none'; // 隐藏正在识别状态 cancelArea.classList.remove('show'); // 隐藏取消区域 voiceRecognizing.classList.remove('canceling'); // 清除预取消状态样式 alert('语音识别结束'); } // 在触摸时,检测是否滑动出了 voice-recognizing 区域 document.addEventListener('touchmove', handleTouchMove, { passive: false }); function handleTouchMove(e) { e.preventDefault(); // 阻止默认的滚动行为 if (isTouching) { const touch = e.touches[0]; const recognizerRect = voiceRecognizing.getBoundingClientRect(); // 判断手指是否离开了 voice-recognizing 区域 if (touch.clientY < recognizerRect.top || touch.clientY > recognizerRect.bottom) { // 进入预取消状态 if (!isCanceling) { voiceRecognizing.classList.add('canceling'); // 改为红色表示预取消 isCanceling = true; } } else { // 手指回到识别区域,取消预取消状态 if (isCanceling) { voiceRecognizing.classList.remove('canceling'); isCanceling = false; } } } } // 取消区域的点击事件 cancelArea.addEventListener('click', cancelRecognition); </script> </body> </html>

浙公网安备 33010602011771号