回顾下 Input type=”file” 的使用
<input type="file" name="" id="">
|
type=”file” 时的属性
accept
它定义了文件 input 应该接受的文件类型。这个字符串是一个以逗号为分隔的 唯一文件类型说明符 列表。由于给定的文件类型可以用多种方式指定,因此当你需要给定格式的文件时,提供一组完整的类型指定符是非常有用的。
<input type="file" id="docpicker" accept=".doc,.docx,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document">
|
capture
如果 accept 属性指出了 input 是图片或者视频类型,则它指定了使用哪个摄像头去这些数据。值 user 表示应该使用前置摄像头和/或麦克风。值 environment 表示应该使用后置摄像头和/或麦克风。如果缺少此属性,则 user agent 可以自由决定做什么。如果请求的前置模式不可用,则用户代理可能退回到其首选的默认模式。
multiple
当指定布尔类型属性 multiple, 文件 input 允许用户选择多个文件。
files
对象每个已选择的文件。如果 multiple 属性没有指定,则这个列表只有一个成员。
webkitdirectory (非标准属性,只能选择文件夹)
一个布尔值,表示是否仅允许用户选择一个目录(或多个目录,如果 multiple 也出现的话)
<input type="file" webkitdirectory >
|
use Web Api
大部分场景下使用 input 上传文件都会去选择隐藏 input 再 diy ui 很是麻烦,学会下面的 Api 将事半功倍(兼容堪忧请注意
!:can i use)。
- window.showOpenFilePicker()
- window.showDirectoryPicker()
- window.showSaveFilePicker()
<button id="upload">upload/save</button>
|
window.showOpenFilePicker
const upload = document.getElementById("upload");
const fileOptions = { types: [ { description: '这只是一个描述', accept: { 'image/*': ['.png', '.gif', '.jpeg', '.jpg'], } }, { description: '上传 dmg', accept: { 'text/plain': ['.dmg'], }, }, ], excludeAcceptAllOption: true, multiple: true, };
div.addEventListener('click', async () => { const result = await window.showOpenFilePicker(fileOptions); console.log(result); console.log(await result[0].getFile()); })
|
options
- excludeAcceptAllOption
excludeAcceptAllOption:boolean
默认 false
,为 true
时隐藏选项
按钮及格式描述
multiple:同,多选
types
types
数组类型,表示允许保存的文件类型列表。数组中的每一项是包含以下属性的配置对象。
- description(可选):用于描述允许保存文件类型类别
- accept:是一个对象,该对象的 key 是 MIME 类型,值是文件扩展名列表。
window.showDirectoryPicker()
同上
window.showSaveFilePicker()
该 Api 为 window 接口中定义的方法,调用方法后会弹出可选择保存路径的文件选择器。
const FileSystemFileHandle = Window.showSaveFilePicker(options);
|
调用 showSaveFilePicker 方法之后会返回一个 FileSystemFileHandle 对象,可使用该方法上的 createWritable 方法写入数据至文件中。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>showSaveFileDemo</title> </head> <body> <div> <button id="upload-btn">upload file</button> </div>
<hr>
<div> <button id="save-btn">save file</button> </div> </body>
<script> const uploadBtn = document.getElementById('upload-btn'); const saveBtn = document.getElementById('save-btn');
let fileInfo = {};
uploadBtn.addEventListener('click', async () => { try { const uploadFileOption = { types: [ { description: '请上传 png', accept: { 'text/plain': ['.png'], } } ], excludeAcceptAllOption: false, };
const files = await window.showOpenFilePicker(uploadFileOption); const file = await files[0].getFile(); if (file) fileInfo = file; } catch (e) { console.error(e, 'upload fail'); } })
const getFileBlob = (file) => new Promise(resolve => { resolve(new Blob([file]), { type: file.type }); })
saveBtn.addEventListener('click', async () => { try { const { name } = fileInfo; const fileName = name?.split('.')?.[0]; const fileSuffix = name?.split('.')?.[1];
const saveFileOption = { suggestedName: `${fileName}-${Date.now()}`, types: [ { description: `保存为 ${fileSuffix}`, accept: { ['text/plain']: [`.${fileSuffix}`] } } ], excludeAcceptAllOption: false, };
const handle = await window.showSaveFilePicker(saveFileOption); const writable = await handle.createWritable(); await writable.write(await getFileBlob(fileInfo)); await writable.close(); } catch (e) { console.error(e, 'save fail') } }); </script> </html>
|
Demo
上传和保存文件的 Demo,纯 js 可放心测试
showSaveFileDemo