capture属性仅对type="file"有效,需配合accept使用,如accept="image/*"才能触发拍照;缺accept或写错值(如"image/jpeg")将失效;https、静态dom、用户手势为硬性前提;微信及旧版ios需降级处理。

capture属性只对type="file"有效,且必须配accept
直接给type="text"或type="button"加capture完全没用,浏览器会静默忽略。它本质是<input type="file">的提示性扩展,不是功能开关。漏写accept,哪怕写了capture也等于白写。
常见错误写法:<input type="file" capture>(缺accept)、<input type="file" accept="image/jpeg" capture>(iOS 和部分 Android 会退化为图库选择)。必须用通配符形式:accept="image/*"✅,accept="image/png"❌。
-
accept="image/*"→ 触发拍照界面(最通用) -
accept="video/*"→ 触发录像界面(但部分 Android 厂商会降级为拍照) -
accept="audio/*"→ 触发录音(Chrome for Android 117+ 稳定,iOS Safari 不支持)
capture="user"和capture="environment"实际效果极差
这两个是 W3C 唯一认可的字符串值,但跨平台表现几乎不可控:
- iOS Safari 直到 16.4+ 才开始识别
capture="environment",且仅 HTTPS 下生效;旧版本直接忽略整条属性,行为退化为普通accept="image/*" - Android Chrome 多数认
capture="environment",但华为 EMUI、小米 MIUI 等定制系统可能仍弹“用哪个应用打开” -
capture="camera"或capture="microphone"是非标写法,Chrome 和 Safari 已废弃,写等于白写 - 不带值的
capture(即布尔属性)在 iOS 上通常等价于capture="user",但无法保证前置——三星某些机型仍开后置
别指望靠它“强制切换镜头”。真要控制前后置,必须用navigator.mediaDevices.getUserMedia() + <video></video>自建流。
HTTPS、静态 DOM、用户手势是硬性前提
只要以下任一条件不满足,capture就会被浏览器静默跳过,退化为相册选择器,且控制台不报错:
- 页面必须运行在
https://协议下(HTTP localhost 可测试,但真机必须 HTTPS) -
<input>必须在初始 HTML 中存在,不能由innerHTML、Vue 的mounted、React 的useEffect动态插入(iOS Safari 会无视) - 触发
.click()必须发生在真实用户手势回调中,比如button.addEventListener('click', () => input.click());不能在setTimeout、Promise.then或scroll事件里调用 - 元素不能被设为
display: none或visibility: hidden(Safari 会跳过该元素) - 用户此前若拒绝过摄像头权限,后续点击不会再次弹 prompt,需引导手动开启
微信和旧版 iOS 必须降级处理
微信内置浏览器(iOS WKWebView / Android X5 内核)基本不响应capture,硬写等于白搭。运行时检测 UA 是唯一可行路径:
- 命中
navigator.userAgent.includes("MicroMessenger")→ 移除capture,改用文案引导:“请在弹出菜单中选择‘拍摄照片’” - 匹配
/OS [1-9][0-5]_/.test(navigator.userAgent)(iOS 15 及以下)→ 同样降级,不依赖capture - 对 iOS 16.4+ 且 HTTPS 环境,可保留
capture,但依然要监听change事件并兼容相册图片 —— 不要假设一定来自摄像头
最稳妥的写法始终是:<input type="file" accept="image/*" capture>,配合 JS 检测 + 引导文案 + URL.createObjectURL()预览,而不是强依赖 capture 是否生效。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











