这篇文章发布于 2021年08月22日,星期日,10:43,归类于 JS API。 阅读 35412 次, 今日 6 次 8 条评论
by zhangxinxu from https://www.zhangxinxu.com/wordpress/?p=10085 鑫空间-鑫生活
本文欢迎分享与聚合,全文转载就不必了,尊重版权,圈子就这么大,若急用可以联系授权。
一、温故而知新
传统在Web端文件上传,都是使用file
类型的表单input
框:
<input type="file">
我们可以通过accept
属性指定选择的文件类型,directory
属性指定是否可以选择文件夹,capture
属性指定前置或后置摄像头。
功能还是很强的。
具体可以见我之前这篇文章:“HTML input type=file文件选择二三事”
但是file
输入框有个致命的缺点,就是 UI 太丑了,并且无法定制。
虽然使用 <label>
元素可以模拟点击按钮,通过 for
属性指向file
input实现类似效果,但是啰嗦了点。
那有没有什么办法点击一个普通的按钮,也能触发文件选择呢?最好可以设置选择文件夹还是文件,设置选择的文件格式类型。
还真有,现代Web不断发展,出现了一个新的API,叫做 File System Access API,可以实现点击任意元素触发文件选择。
二、showOpenFilePicker方法
假设页面上有个按钮,其HTML如下所示:
<button id="button">选择图片</button>
则下面几行JavaScript代码就可以实现点击按钮出现文件选择:
button.addEventListener('click', function () {
// 打开文件
window.showOpenFilePicker();
});
真是简单又粗暴,直接又了当。
//zxx: 如果你看到这段文字,说明你现在访问是体验糟糕的垃圾盗版网站,你可以访问原文获得很好的体验:https://www.zhangxinxu.com/wordpress/?p=10085(作者张鑫旭)
当然,我们也可以使用 showDirectoryPicker()
方法来选择文件夹。
button.addEventListener('click', function () {
// 打开文件夹
window.showDirectoryPicker();
});
由于两个API参数和作用类似,因此里只详细介绍文件的选择。
文件类型、多选与否的指定
showOpenFilePicker(options)
方法中是可以传参的,具体支持的参数如下:
其中,options是可选参数,支持下面这些属性:
- multiple
- 布尔值,默认值是 false ,表示只能选择一个文件。
- excludeAcceptAllOption
- 布尔值,默认值是 false ,表示是否排除下面 types 中的所有的accept文件类型。
- types
- 可选择的文件类型数组,每个数组项也是个对象,支持下面两个参数:
description
:表示文件或者文件夹的描述,字符串,可选。accept
:接受的文件类型,对象,然后对象的键是文件的MIME匹配,值是数组,表示支持的文件后缀。具体可以下面的示意。
例如下面的JS代码执行就是可以一次性选择多张本地桌面图片:
window.showOpenFilePicker({
types: [{
description: 'Images',
accept: {
'image/*': ['.png', '.gif', '.jpeg', '.jpg', '.webp']
}
}],
// 可以选择多个图片
multiple: true
});
三、演示-点击按钮选择并显示多图
上面知道了选择文件,但是如何处理选择后的文件呢,下面有个例子,对大家学习会很有帮助。
完整代码如下:
<button id="button">选择图片</button> <p id="output"></p>
button.addEventListener('click', async function () { // 打开文件 const arrFileHandle = await window.showOpenFilePicker({ types: [{ accept: { 'image/*': ['.png', '.gif', '.jpeg', '.jpg', '.webp'] } }], // 可以选择多个图片 multiple: true }); // 遍历选择的文件 for (const fileHandle of arrFileHandle) { // 获取文件内容 const fileData = await fileHandle.getFile(); // 读文件数据 const buffer = await fileData.arrayBuffer(); // 转成Blod url地址 let src = URL.createObjectURL(new Blob([buffer])); // 在页面中显示 output.insertAdjacentHTML('beforeend', `<img src="${src}">`); } });
这个例子有对应的demo,您可以狠狠地点击这里:文件访问API 触发图片选择demo
点击demo页面这个蓝色按钮:
选择自己电脑中对应的图片,例如我选择了2张不错的PNG图片:
结果在Web页面上成功预览了图片效果,如下截图所示:
是不是跟传统的file文件选择很类似。
由于这些全新的API都是走的Promise,因此,可以使用async、 await等新的JS语法,避免各种乱糟糟的回调,代码更简洁更易读了。
是不是很赞!
四、可惜是个新API
对于不喜欢HTML表单元素,喜欢JavaScript代码一把梭的开发者而言,这个API会很亲近很喜欢,但是,遗憾的是,这个API出来的比较新,去年下半年才出来,Safari浏览器并不支持,因此,不能直接使用。
不过,有不少项目做了mix混合处理,也就是写了个 JS,支持的浏览器使用 File System Access API,不支持的浏览器还是使用传统的 <input type="file">
,例如谷歌实验室的这个项目 browser-fs-access
如果是文件保存或下载,则可以试试window.showSaveFilePicker()
这个 API,有时候可以介绍下,当然,实际开发,文件下载肯定是使用 FileSaver.js,这可以文件下载当仁不让的王者,标杆项目。
其他限制
- 需要https环境,如果是本地localhost 不受此限制。
- 不能在 iframe 内使用,因为被认为不安全
五、结语碎碎念
下午参与了掘金的一个直播活动,讲关于写作的,大家有兴趣可以关注下,应该有录播视频和PPT,活动宣传页地址是这个。
今天的行程正好解答了其中关于写作时间的问题,我下午直播,直播完去钓鱼,钓完鱼回家吃饭,吃晚饭就写了这篇文章,时间就是这么来的,管理好,下目标,不做完不睡觉。
以上~
每天学习一个API,日积月累,过几年就是基础API巨佬啦。
欢迎转发,评论,文中有表述错误,也欢迎指正。
最后,友情附上 MDN 关于 File System Access API的链接:File_System_Access_API
本文为原创文章,欢迎分享,勿全文转载,如果实在喜欢,可收藏,永不过期,且会及时更新知识点及修正错误,阅读体验也更好。
本文地址:https://www.zhangxinxu.com/wordpress/?p=10085
(本篇完)
- 纯前端JS zip打包文件并下载 (0.703)
- 做了个纯前端JPG/PNG尺寸缩放+压缩的在线工具 (0.703)
- HTML input type=file文件选择表单元素二三事 (0.297)
- CSS ::file-selector-button伪元素简介 (0.297)
- 理解DOMString、Document、FormData、Blob、File、ArrayBuffer数据类型 (0.162)
- XMLHttpRequest实现HTTP协议下文件上传断点续传 (0.162)
- 了解HTML/HTML5中的download属性 (0.162)
- JS前端创建html或json文件并浏览器导出下载 (0.162)
- HTML5 file API加canvas实现图片前端JS压缩并上传 (0.162)
- SVG <foreignObject>简介与截图等应用 (0.162)
- 学习了,CSS中内联SVG图片有比Base64更好的形式 (RANDOM - 0.162)
旭哥yyds!
旭哥,崇拜已久的旭哥,你可以分享一篇页面渲染的流程吗?我在网上查资料,没有找到一篇让人看了就明白的文章。这个问题一直困扰着我
什么时候直播一下钓鱼
虽然但是,Windows这个选文件对话框最不好看要怎么改。
太好了,直播完还能去?,钓鱼佬永不为奴!!!
感谢大佬分享,向你学习。
Google 做了 ponyfill。
https://github.com/GoogleChromeLabs/browser-fs-access
When could it finally come to everyone? It is always amazing !