原生语音输入需用webkitspeechrecognition(chrome/edge),https+用户手势触发,设lang="zh-cn"、interimresults:true,onresult中判isfinal填值,提交前stop()并延时或禁用按钮;safari/firefox不支持。

怎么让 <input> 或 <textarea></textarea> 支持语音输入
浏览器原生就支持,不用接第三方 API —— 关键是用对 webkitSpeechRecognition(Chrome/Edge)或 SpeechRecognition(标准名),但得手动加触发逻辑。HTML 表单本身不提供语音按钮,type="text" 或 type="search" 都没内置语音图标,必须自己绑事件、调起识别器。
常见错误现象:Uncaught ReferenceError: webkitSpeechRecognition is not defined(Safari/Firefox 直接报错)、点击无反应、识别后不填入表单字段。
- 只在 HTTPS 页面下可用(localhost 也行,HTTP 域名会静默失败)
- 必须用户主动手势触发(比如 click、tap),不能 onload 自动启动
- 识别结果默认是只读的
event.results[0][0].transcript,要手动赋值给input.value或textarea.value - Chrome 119+ 开始,
continuous: true默认被限制为 false,想连续识别得显式设interimResults: true并处理多段结果
webkitSpeechRecognition 初始化时哪些参数不能乱设
参数设错会导致识别卡死、不返回结果、或反复触发 onend。最常踩的坑是把 lang 写成 "zh-CN"(正确)写成 "zh" 或 "chinese",结果识别率暴跌;或者漏掉 interimResults: true 却又去读 event.results[i][j].isFinal === false 的内容。
-
lang必须用 BCP 47 格式,中文推荐"zh-CN",英文用"en-US",错写成"zh"会 fallback 到默认语言(通常是英文) -
continuous: false是默认值,适合单次语音输入;设为true后必须手动调recognition.stop(),否则可能持续监听并耗电 -
maxAlternatives: 1足够用,设高了不提升准确率,反而增加解析开销 - 别在
onresult里直接修改 DOM 并触发input事件——有些框架(如 Vue)会拦截,应改完 value 后显式调input.dispatchEvent(new Event('input', { bubbles: true }))
表单提交前怎么确保语音识别已结束且文本已落库
用户点「提交」时,语音识别可能还在 onend 过程中,或者 onresult 还没执行完,导致提交的是空值或旧值。不能依赖 recognition.onend 立即认为文本就绪——它只表示音频流停了,异步的 onresult 可能还没跑完。
立即学习“前端免费学习笔记(深入)”;
- 在
onresult里用event.results[event.results.length - 1][0].isFinal === true判定最终结果是否到达,再更新字段 - 提交按钮绑定的 handler 里,先检查
recognition && recognition.state === 'listening',如果是,调recognition.stop()并加个短延时(setTimeout(() => submit(), 100))等结果落地 - 更稳的做法:禁用提交按钮,直到
onresult中拿到isFinal === true后才启用,避免竞态 - 别用
recognition.abort()替代stop()——abort()会清空所有结果,stop()才保证已识别的部分能进onresult
Safari 和 Firefox 下语音识别完全不可用怎么办
不是 bug,是现状:webkitSpeechRecognition 是 Chrome/Edge 专属,Safari 和 Firefox 没实现 Web Speech API。强行检测并调用只会报 undefined,没有降级路径可言。
- 先判断是否存在:
if ('webkitSpeechRecognition' in window || 'SpeechRecognition' in window),不存在就隐藏语音按钮或显示提示 - 不要试图用 WebRTC 录音 + 第三方 ASR(如 Whisper.cpp、Vosk)补位——延迟高、需上传音频、隐私风险大,和原生体验差两个量级
- 如果业务强依赖语音输入,只能引导用户换 Chrome/Edge,或接受“仅限部分浏览器”作为产品约束
- 某些安卓 WebView(如微信内嵌)可能有定制版 speech API,但行为不一致,建议统一按“仅 Chromium 内核”来设计交互流程
语音识别真正难的不是调 API,而是处理中间态:用户说一半取消、网络抖动导致 onend 提前、识别出错后手动编辑与语音内容混杂……这些边界情况比初始化代码多三倍。











