💰 点进来就是赚到知识点!本文带你用 JS 实现文件选择功能,点赞、收藏、评论更能促进消化吸收!
🚀 想解锁更多 Web 文件系统技能吗?快来订阅专栏「Web 玩转文件操作」!
📣 我是 Jax,在畅游 Web 技术海洋的又一年,我仍然是坚定不移的 JavaScript 迷弟,Web 技术带给我太多乐趣。如果你也和我一样,欢迎关注、私聊!
在本专栏的第一篇文章中,我们重新认识了 <input type=”file”>
这位老伙计,挖掘了它的几个彩蛋特性。在做文件上传时,input 标签确实是我们的黄金搭档。但是为了方便调教 CSS 样式,我们往往需要把 input 标签藏起来,而用其他 HTML 元素来做 UI 代理。似乎是我们只馋 <input type=”file”>
的身子,并不会给它一个名分 🐶。
但其实,不一定非要经过 input 标签这个中间商,我们是可以直接用 JavaScript 和系统进行文件交易的!
戳这里去看一个 demo!
在上面的示例中,左侧是传统 input 组合拳,右侧是纯 JavaScript 实现,而 JavaScript 实现的奥义,就是 showOpenFilePicker
这个方法。
使用方法
基础用法
showOpenFilePicker
是全局对象 window
的一个子方法,所以我们可以直接调用:
const [handle] = await showOpenFilePicker();
执行这个方法会得到一个 Promise
,并从中 resolve
出一个数组,数组元素是一个个 FileSystemFileHandle
类型的对象。你可能对这个类型很陌生,但没关系,我们暂且把它当成是文件对象的容器即可。但关于 FileSystem 的相关知识,我们会在下一篇文章中涉及到,请持续关注!
FileSystemFileHandle
对象具有一个 getFile
方法,返回包含文件对象的 Promise
:
const [file] = await handle.getFile();
我们透视一下 file 对象的结构,你会发现和用 input 标签拿到的文件对象是完全一样的。
这样,无需引入和处理文件 input,我们也能实现选取文件的功能。
可选参数
我们知道,在文件 input 上可以配置 multiple
、accept
等特性来满足特定的文件要求。相对应地,通过给方法传入配置参数,我们可以在 showOpenFilePicker
方法上复刻出同样的表现,甚至可以实现更强大的功能。
showOpenFilePicker({id: '',multiple: true,startIn: 'desktop',types: [{ ... }],excludeAcceptAllOption: true
})
- id:指定一个字符串标识,相同的
id
会指向同一个文件路径。例如我们在首次调用时传入id: ‘a’
,用户在弹出窗口中选择了dirA/subDirB/c.js
这个文件。在后续逻辑中,我们再次调用了showOpenFilePicker({ id: ‘a’ })
,打开的窗口会自动定位到dirA/subDirB/
这个路径。 - multiple:这个无需多言,与 input 标签上的
multiple
特性一致。 - startIn:该属性接收固定的枚举值(desktop、documents、downloads、music、pictures、videos),以 desktop 为例,可以直接打开桌面文件夹,方便快捷。但只支持通用操作系统的通用文件夹。
- excludeAcceptAllOption:这个属性名非常值得吐槽,又长又七拐八弯的,我们可以直接理解为「限制文件格式」,为
true
时需要指定types
,意为只能选中给定文件格式;为false
则代表格式不限。 - types:一个对象数组,用于指定我们期望的文件格式。比如我们只想接收
.jpg
格式的图片,就可以这样配置:
showOpenFilePicker({types: [{description: '图片',accept: {'image/*': ['.jpg']}}]
})
使用限制
当然,我们在调用 showOpenFilePicker
时还需要注意一些限制条件:
- 仅支持
https
协议的网页。 - 必须由用户动作触发。这个条件与音视频自动播放类似,都需要有用户操作在先,不可以自动触发。
这些限制都是出于安全考虑或者防止滥用,可以给用户体验带来很大的保障。
写在结尾
恭喜你读完了本文,你真棒!
这次我们一起探究了 showOpenFilePicker
方法,学会了如何不依赖文件 input 实现文件选取功能。请继续关注我的专栏,下一篇我们将会继续深入 File API!