前言
先说说我做这个的场景,我们是开发的h5应用,客户是用的rn写的原生app,h5应用是内嵌在app里面的。
具体需求就是,在点击上传附件的时候,会从底部有个弹出层,分别显示相册、相机、拍摄三个图标以供用户选择上传什么类型的文件。
结论就是:h5实现有兼容问题,在部分安卓手机可以直接访问到手机相册,在ios是需要在弹出一个选择框让用户进行选择,这样的操作是客户不能接受的。最后拍摄视频和拍照h5来实现,相册是调用原生的方法来实现的。
ps:我和原生联调的时候还尝试过,当用户选择相册以后原生可以拿到file,然后通过转换成base64传递给h5,不过加密和解码也有一定兼容性,而且视频太大的话base64字符串太长会有问题。
一、input的两个参数
-
accept:
在上面的场景中,我们实际需要用到的就三个参数
可以接受MIME类型,拍摄照片:image/* | 拍摄视频: video/* | 相册或者可选项: **‘’**空字符串 -
capture:
官方文档只承认2个值,user和environment。
但是根据查阅一些文档还有chatgpt的回答,还存在filesystem | camera | camcorder这三个值,仅供参考。
总结一下:
1.在安卓中必须加上capture,否则只能调用相册。
2.在ios中加上了capture就只能调用摄像头不能调用相册。
二、代码示例
1.html部分
三个icon的点击事件就不展示了
<input
style="display: none;"
ref="uploadInput"
type="file"
:accept="acceptMap[chooseType]"
@change="fileChange"
/>
绑定的accept根据选中的类型来实时更改
acceptMap:{
1:'',
2:'image/*',
3:'video/*'
}
chooseType = 1 | 2 | 3
2.js部分
当点击icon以后
const uploadInput = this.$refs.uploadInput
// 这里要根据不同系统来判断添加或删除capture
uploadInput.setAttribute('capture','filesystem')
// 或者
uploadInput.setAttribute('capture','environment')
// 或者
uploadInput.removeAttribute('capture')
3.上传
// 如果是其他定制需求需要新加判断
this.$refs.uploadInput.click()
总结
在使用input在h5进行文件上传,因为涉及使用的浏览器内核不一样导致安卓和ios选择相册和拍摄会有兼容问题,在部分手机浏览器中我们只需要修改accept和capture就可以实现区分拍摄和相册等操作。但是在有的浏览器中即便是加了capture也会出现拍摄和相册让你选择的情况,像这种的话h5目前还没有更好的办法如果有同学遇到可以一起探讨交流。