input标签不支持原生语音输入属性,x-webkit-speech等已废弃;必须用web speech api的webkitspeechrecognition手动实现,需检测兼容性、设置语言、处理临时/最终结果,并为移动端准备降级方案。

input 标签本身不支持语音输入,浏览器没有为其提供原生的语音输入属性(比如 speech、voice 或 x-webkit-speech 这类属性早已被移除)。想在网页中实现语音输入,必须绕过 input 的限制,用 Web Speech API 手动接管。
为什么不能给 input 加个属性就启用语音?
Chrome 曾在 2013 年左右支持过 input[type="text"] 的 x-webkit-speech 属性,但该功能已被彻底废弃,现代 Chrome、Edge、Firefox 均不再识别。试图写 <input speech> 或 <input x-webkit-speech> 不会触发任何行为,控制台也无提示——它就是无效 HTML。
webkitSpeechRecognition 是唯一可行的起点
目前跨主流桌面 Chrome/Edge(基于 Chromium)实现语音输入,只能依赖 webkitSpeechRecognition 构造函数。它不是标准 API,但仍是事实上的唯一选择:
- 必须显式检测
window.webkitSpeechRecognition是否存在,不存在就降级(比如显示“仅 Chrome/Edge 支持”) -
recognition.lang必须设为明确的语言标签,如"zh-CN"或"en-US";不设或设错会导致识别失败或返回空字符串 -
recognition.interimResults = true才能拿到实时流式结果;设为false会等用户停顿后才返回一次最终结果,体验断层 - 每次调用
recognition.start()前,建议先recognition.stop(),否则连续点击可能触发error: "aborted"
如何把识别结果填进 input 或 textarea?
不能绑定事件到 input 上监听语音,而是要在 recognition.onresult 回调里手动赋值:
recognition.onresult = function(event) {
const result = event.results[event.resultIndex][0].transcript;
const inputEl = document.getElementById("my-input");
if (event.results[event.resultIndex].isFinal) {
inputEl.value += result + " ";
} else {
inputEl.value = inputEl.value.replace(/[^ ]*$/, result); // 替换最后单词
}
};
注意点:
- 别直接覆盖
input.value,否则用户已输入的内容会被清空 - 临时结果(
isFinal === false)需要做增量更新,否则光标会跳到开头 - 移动端需额外处理权限弹窗阻塞问题:iOS Safari 完全不支持,Android Chrome 需用户首次点击授权麦克风
移动端和 Safari 的现实约束
Web Speech API 在移动端极度受限:
- iOS Safari:完全不支持
webkitSpeechRecognition,检测始终为undefined - Android Chrome:支持,但首次使用会弹出系统级麦克风权限请求,且无法预授权——用户必须点“允许”,否则
start()抛error: "not-allowed" - 所有移动端浏览器都不支持
continuous = true模式下的长时间监听,通常 30 秒左右自动end
真正要覆盖全平台,不能只靠 Web Speech API;得准备 fallback 方案,比如调用系统语音键盘(inputmode="text" + 软键盘麦克风按钮),或者引导用户使用系统级语音输入(如 Android 的 Gboard 语音键入)。











