首页/文章/javascript

绕过中间商,不用 input 标签也能搞定文件选择

2024-09-09
12715 分钟
...

在本专栏的第一篇文章中,我们重新认识了 <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 上可以配置 multipleaccept 等特性来满足特定的文件要求。相对应地,通过给方法传入配置参数,我们可以在 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!

如果您觉得这篇文章有帮助,请点个赞吧~

分享文章

相关文章

更多文章 →
javascript2025-09-18
JavaScript 的多线程能力:Worker
如果你写过一些计算量稍大的 JavaScript 代码,比如图像处理、大量数据排序或者复杂的算法,你几乎肯定遇到过浏览器“卡死”的现象。点击页面没反应,动画也停了,就像整个世界都静止了。 这就是主线程被阻塞的典型后果。因为主线程既要负责执行 JavaScript,又要负责渲染页面、响应用户操作,一旦它被繁重的计算任务占满,就无暇顾及其他,用户体验便直线下降。 这个问题的根源,正是“主线程是单线程的”。那么,如何解决呢? 答案很简单:把这...
学习面试
javascript2025-09-10
手把手教你实现一个EventEmitter
你是不是也遇到过这种情况:代码里各种事件监听和触发,回调函数套了一层又一层,最后自己都理不清哪个事件先触发、哪个后触发了? 别担心,今天我就带你从零开始实现一个自己的事件触发器(EventEmitter),让你彻底掌握事件驱动的精髓,代码清晰度直接提升200%! 为什么要懂EventEmitter? 先说说为什么我们要关心这个。Node.js的核心就是事件驱动,比如文件读写、网络请求,都是通过事件来处理的。不会EventEmitter,...
学习面试
javascript2025-08-09
Web Worker 多线程魔法
你是否曾遇到过网页因为复杂计算而卡顿的情况?今天,让我们一起探索Web Worker的神奇世界,看看如何用多线程技术解决性能瓶颈,并实现流畅的图片压缩功能! 为什么需要Web Worker? 想象一下,你在一个繁忙的餐厅里,只有一位服务员(主线程)负责点餐、上菜、结账所有工作。当客人突然暴增时,这位服务员就会手忙脚乱,其他客人只能干等着… 这就是JavaScript的现状—— 单线程 !所有任务都在一个线程中排队执行,一旦遇到复杂计算(...
学习面试
javascript2025-08-07
🌐AST抽象语法树
AST 是前端开发中一个非常重要的概念,它就像是代码的“编译器”,能够帮助我们理解和操作代码。本文将深入探讨 AST 的原理和应用,带你从零开始了解 AST。 一、什么是 AST? AST(抽象语法树)是一种树形结构,用于表示程序代码的语法结构。它将代码分解为一系列的节点,每个节点代表代码中的一个元素,如变量、函数、表达式等。AST 是编译器和解释器的基础,也是代码分析和转换的关键工具。 1\. AST 的结构 AST 的结构通常包括以...
学习面试
javascript2025-08-05
打字机效果是如何实现的
分析效果 使用 AI 对话的时候,文字是一个字一个字蹦出来的?它不是等所有内容生成完毕后一次性展示,而是以一种流畅、实时的“打字机”效果呈现,这种体验的背后,隐藏着一种高效的Web技术。它就是 服务器推送事件(Server Sent Events,简称 SSE) 什么是 SSE 从根本上说,SSE 是一种允许服务器 单向 、 持续 地向客户端(浏览器)推送数据的Web技术。 可以把它想象成一个 电台广播 : 服务器 是广播电台,持续不断...
学习面试
javascript2025-08-04
Promise 从原理到实现
前言 是 异步编程的核心概念之一,它为我们提供了一种更优雅的方式来处理异步操作。 本文将全面剖析 的工作原理,并逐步实现一个符合 规范的 。 正文 一、Promise 基础概念 代表一个异步操作的最终完成(或失败)及其结果值。它有 种状态: 1. pending : ,既不是成功,也不是失败状态 2. fulfilled :意味着操作 完成 3. rejected :意味着操作 状态一旦改变就不能再变,只能从 变为 ,或从 变为 。 二...
学习面试

评论

请登录后发表评论

去登录
加载评论中...

目录