web前端文件上传可选择的4种方式

news2024/11/19 17:03:01

在web前端开发中,文件上传属于很常见的功能,不论是图片、还是文档等等资源,或多或少会有上传的需求。一般都是从添加文件开始,然后读取文件信息,再通过一定的方式将文件上传到服务器上,以供后续展示或下载使用。
本文将讲述文件上传中所能用到的4种添加读取文件的方式:

  • input上传控件
  • 拖拽文件
  • 粘贴文件
  • File System Access API

input上传控件

首先介绍的,就是最常用的html表单控件:input[type=file],它允许用户打开系统的文件选择框,选择相应文件后加载并读取到相关文件信息,它支持单个文件或多个文件,多文件选择增加属性:multiple
input上传控件的浏览器支持度最高,作为html的基础标签功能,一直都是web开发中使用最多的一种文件上传方式。
它支持的主要属性:

  • multiple:允许用户选择多个文件进行添加
  • accept:指定文件上传时能接受的文件类型(MIME),如 image/pngimage/*video/* 等等

html控件代码如下,接受批量添加图片文件:

<input id="fileInput" type="file" accept="image/*" multiple onchange="selectFile()" />

以上代码添加了 onchange 事件,当选中不同文件时,可以获取到文件信息:

const fileInput = document.getElementById('fileInput')
function selectFile () {
  const file = fileInput.files[0]
}

上面的js代码,就是监听事件的函数,通过元素对象,读取正在添加的文件信息。
或者也可以添加事件监听器,同样能读取到文件信息:

document.getElementById('fileInput').addEventListener('change', (e) => {
  const file = e.target.files[0]
}, false)

这里读取的上传控件元素对象的文件属性 files,它是 FileList 对象,一个针对 File 对象的集合。

文件信息是使用 File 对象API,用于接收文件,具体的介绍可见博文 详解前端二进制:Blob、File、FileReader、ArrayBuffer、TypeArray、DataView

修改上传控件样式

input文件上传控件,之前被诟病比较多的就是样式太单一,在整体设计风格上会有很多局限,但我们可以使用css样式中的一个伪元素来美化该控件。
这个伪元素就是 ::file-selector-button,通过它可以对上传控件按钮进行颜色字体背景边框等进行各种样式设置。具体信息可见博文CSS伪元素详解以及伪元素与伪类的区别

input::file-selector-button {
  border: 1px solid #f00;
  font-size: 20px;
  border-radius: 5px;
  background-color: azure;
}

以上代码,即通过伪元素对上传控件按钮进行了样式的修改,效果如下图。
在这里插入图片描述
当然,这个伪元素只能修改按钮的样式,至于上传控件的其他部分包括文字内容,无法修改,仍然会较影响设计,这时候我们就需要使用另外的方式,比如隐藏上传控件。

隐藏上传控件

我们只需要让上传控件隐藏不显示,但在点击的时候还能够触发上传控件的文件选择框,就能达到自定义各种好看样式的上传控件的目的。
隐藏上传控件的方式有很多种,下面介绍其中一种,通过透明度的方式,先设置一个外部div元素,div内添加input上传元素,并设置透明度为0,达到不显示的目的,代码如下:

<div class="input-container">
  点击 <span style="color: red;">选择文件</span> 进行上传
  <input class="input-file" type="file" name="file" multiple="multiple" />
</div>
.input-container {
  position: relative;
  width: 250px;
  margin: 20px 0;
}
.input-file {
  position: absolute;
  top: 0;
  left: 0;
  margin: 0;
  opacity: 0;
}

以上代码,input上传控件元素通过绝对定位的方式置于div上层,透明度为0隐藏,视觉上只会显示底层div的内容(我们可自定义样式),但input控件会优先响应点击事件,这样就可以达到添加文件的目的。
当然,类似隐藏的方法还有多种,基于css样式实现,可以设计出更多更好看的文件上传组件。

拖拽文件

第二种介绍的添加文件的方式是拖拽文件,就是通过拖放(drag and drop)过程中的事件监听读取文件。主要针对的是三个拖拽相关的事件:

  • dragenter:拖拽进入当前节点时触发
  • dragover:拖拽位于节点上方时,持续触发
  • drop:当拖拽至目标节点,释放时触发

我们只需要在页面上添加一个div元素标签,设置一定的区域大小,对这个元素的拖放事件进行监听即可:

const dropArea = document.getElementById('dropArea')
const stopPropagation = (e) => {
  e.stopPropagation()
  e.preventDefault()
}

dropArea.addEventListener('dragenter', stopPropagation, false)
dropArea.addEventListener('dragover', stopPropagation, false)
dropArea.addEventListener('drop', (dragEvent) => {
  stopPropagation(dragEvent)
  const file = dragEvent.dataTransfer.files[0]
}, false)

以上代码,监听了拖放事件,当我们从电脑上拖动一个文件到指定div区域内,释放以后,就能获取了drop事件对象 DragEvent,它拥有一个独有属性 dataTransfer,是一个 DataTransfer 对象,能读取到文件属性 ‘files’。
接下来,我们了解下 DataTransfer 对象。

Datatransfer

Datatransfer 对象用于获取拖放事件中传输的数据。所有的拖放事件都包含一个该类型的属性。
我们在事件监听中读取到该对象后,可以从它的属性里读取到需要的数据,如文件信息。
该对象除了从拖放事件中获取以外,还能从 ClipboardEvent.clipboardData 剪切板事件上获取(后文会介绍)。

Datatransfer 对象拥有的属性和方法:

  • dropEffect:获取当前选定的拖放操作类型或者设置的为一个新的类型。值必须为none, copy, link或move。
  • effectAllowed:提供所有可用的操作类型。必须是none, copy, copyLink, copyMove, link, linkMove, move, all or uninitialized 之一。
  • files:包含数据传输中可用的所有本地文件的列表。
  • items:只读,提供一个包含所有拖动数据列表的DataTransferItemList对象。
  • types:只读,一个提供dragstart事件中设置的格式的字符串数组。
  • clearData():删除与给定类型关联的数据。不给定参数则删除所有
  • getData():检索给定类型的数据。
  • setData():设置给定类型的数据。不存在则添加到末尾,存在则替换相同位置的数据。
  • setDragImage():用于设置自定义的拖动图像。

粘贴文件

除了拖拽文件以外,还有依赖剪切板的粘贴文件的方式,通过复制文件,并在指定元素区域内粘贴文件,这个时候,我们监听元素的 onpaste 事件,就可以得到想要的文件了。

onpaste事件:在将剪切板内容粘贴到文档时触发的事件,事件对象 ClipboardEvent,拥有一个 clipboardData 只读属性,存放剪切板的数据,它是一个DataTransfer对象(见上文)。
有了这个事件和相应的属性,实现文件读取就比较方便了:

document.getElementById('textarea').onpaste = (clipboardEvent) => {
  clipboardEvent.stopPropagation()
  clipboardEvent.stopImmediatePropagation()
  
  const { items, files } = clipboardEvent.clipboardData

  if (files && files.length) {
    const file = files[0]
  }
}

以上代码,通过监听一个 textarea 元素的 onpaste 事件,读取到 clipboardData 属性,包含了 files,就读取到了文件信息,使用上也较为方便。

粘贴的方式,除了文件以外,文本内容之类的数据也可以处理。

File System Access API

File System Access API 文件系统访问API,允许访问读写文件及管理功能。它拥有多个API对象和方法,能够从用户的本地设备上进行文件交互,核心功能包括读写文件、访问目录结构等等。它的浏览器支持正在慢慢变好,chrome、edge与opera都已支持,然而firefox还不支持。
下文将着重介绍文件读取的API对象和方法,让我们能了解这种新的文件读取的方式。

showOpenFilePicker

showOpenFilePicker 是用于打开文件选择框,选中并添加文件的一个异步方法,支持 async/await
它的语法:showOpenFilePicker(options)

options 可选属性对象:

  • multiple:布尔值,是否能选择多个文件。默认false,表示只能选择一个文件。
  • excludeAcceptAllOption:布尔值,是否排除types对象中所有的accept文件类型。默认false,不排除。
  • types:可选的文件类型数组,数组元素也是对象,支持以下参数:
    • description:表示文件或者文件夹的描述。
    • accept:接受的文件类型,对象,用法如 { 'image/*': ['.png', '.gif', '.jpeg', '.jpg'] }

showOpenFilePicker 方法返回一个 FileSystemFileHandle 对象数组,用来处理文件信息。

FileSystemHandle 对象提供一个系统文件的句柄,用于读取文件对象。它提供了一个方法:getFile(),返回文件对象,支持 async/await
下面看一个具体的示例:

<button id="openImageFile">打开图片</button>
document.getElementById('openImageFile').addEventListener('click', async () => {
  const handle = await showOpenFilePicker({
    multiple: true,
    types: [{
      description: '图片',
      accept: { 'image/png': ['.jpg', '.png'] }
    }]
  })

  if (handle && handle.length) {
    const handleFile = handle[0]
    const file = await handleFile.getFile()
  }
}, false)

以上代码,通过按钮的click事件,使用showOpenFilePicker方法打开选择文件框,添加一个文件。

上传

读取到文件信息以后,就是将文件上传到服务器上,可以使用基本的上传方式,HTML表单:

<form action="url" enctype="multipart/form-data" method="post">
  <input name="fileInput" type="file" />
  <button type="submit">提交</button>
</form>

以上代码,就是通过form表单,以 post 的方式将文件上传到 action 属性对应的url上传链接。
这种方式一般针对的就是input文件上传控件。

除了HTML表单的方式以外,我们还是可以使用 FormData 对象,构造一个表单数据,通过ajax等方式进行异步数据上传:

const formData = new FormData()
formData.append('file', file, file.name)

const xhr = new XMLHttpRequest()
xhr.open('POST', 'url', true)
xhr.send(formData)

以上代码,就是通过构造一个 formData 实例,添加文件数据,通过 xhr 的方式提交到对应的url上传链接。
构造 FormData 对象的方式,适用于以上4种文件读取方式,只要获取到文件信息,就可以通过这种方式上传到服务器。

总结

本文总结了前端web当前能够添加读取文件的4种方式,如果我们需要开发一个比较完善的图片上传组件,那么可能需要点击、拖拽、粘贴多种功能,这就需要使用到前三种文件读取方式。文件系统访问API鉴于兼容性还有待提升,我们可以作为后备的方案使用。
有了文件读取的方式,那我们要完成上传功能,就可以使用 HTML表单 提交,或者 FormData 对象上传了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/409036.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

WEB核心【记录网站登录人数,记录用户名案例】Cookie技术实现

目录 &#x1f482; 个人主页: 爱吃豆的土豆&#x1f91f; 版权: 本文由【爱吃豆的土豆】原创、在CSDN首发、需要转载请联系博主&#x1f4ac; 如果文章对你有帮助、欢迎关注、点赞、收藏(一键三连)和订阅专栏哦 &#x1f3c6;人必有所执&#xff0c;方能有所成&#xff01; &…

npm ERR! code ERESOLVE npm ERR! ERESOLVE unable to resolve dependency tree

当我们拿到一个前端项目的时候&#xff0c;想要把它运行起来&#xff0c;首先是要给它安装依赖&#xff0c;即cd到当前项目根目录下去执行npm install命令&#xff0c;然后有一定几率在终端你会遇到这样的报错&#xff1a; npm ERR! code ERESOLVEnpm ERR! ERESOLVE unable to…

HTML基础————table标签

1.什么是table&#xff1f; table是html中的表格&#xff0c;由tr、td、th元素组成。 tr 元素定义表格行&#xff0c;th 元素定义表头&#xff0c;td 元素定义表格单元 2.可选的属性 属性描述border定义表格的边框cellpadding单元格内内容与单元格边的间距cellspacing单元格…

Vite配置环境变量

Vite配置代码环境变量和 Vue2 的配置差不多&#xff0c;都是依靠 .env 文件夹来实现 详情可到 Vite 官网的环境配置里了解&#xff1a;环境变量和模式 {#env-variables-and-modes} | Vite中文网 一、在src同级下创建 .env.production 生产模式和 .env.development 开发模式两…

基于 vue3 element-plus 的暗黑模式

前言 element-plus2.2.0 已经开始支持暗黑模式了 通过在html标签上添加一个名为 dark 的类来启用 基于 vue3 & element-plus 的项目现在可以方便的添加暗黑模式 一、基本使用 因为是通过在html标签上添加 dark 类&#xff0c;可以自行实现切换 但为了方便切换以及进一…

WEB核心【会话技术】第十五章

目录 &#x1f482; 个人主页: 爱吃豆的土豆&#x1f91f; 版权: 本文由【爱吃豆的土豆】原创、在CSDN首发、需要转载请联系博主&#x1f4ac; 如果文章对你有帮助、欢迎关注、点赞、收藏(一键三连)和订阅专栏哦 &#x1f3c6;人必有所执&#xff0c;方能有所成&#xff01; &…

【JavaScript】VUE前端实现微信版录制音频wav格式转化成mp3格式和Base64

一、前言 前端有个需求是要实现一个像微信一样&#xff0c;按住录音&#xff0c;松开发送语音&#xff0c;期间踩了不少坑&#xff0c;特地记录一下&#xff0c;主要用到两个库 js-audio-recorder &#xff1a;负责录制音频&#xff0c;支持的格式只有wav、pcmLAMPjs &#x…

三更Blog项目总结(p1~p40)

文章目录项目创建——多模块开发功能业务逻辑总结热门文章列表分类列表分页文章查询文章详情友链查询登录功能退出登录视频地址&#xff1a;SpringBoot项目实战-前后端分离博客项目-Java项目_哔哩哔哩_bilibili 项目创建——多模块开发 整个系统分为前台模块&#xff08;blog&…

三步解决微信小程序cdn加速(资源大小超过200k)

刚开始开发小程序的时候&#xff0c;上传代码会遇到这样的问题&#xff1a;图片和音频资源大小超过 200 K 下面是官方建议 【建议】小程序代码包里可以存放一些必要的静态资源&#xff08;例如tabbar的icon等&#xff09;&#xff0c;不过静态资源体积过大也会影响小程序代码…

运行安装vue3+vite+Ts项目报错,无法加载vite.config.ts文件(failed to load config from D:\XXX\vite.config.ts)

git 上面拉别人的vue3viteTs项目&#xff0c; 安装依赖成功之后运行&#xff0c;出现报错 failed to load config from D:\XXX\vite.config.ts 百度搜索的结果是用 pnpm进行下载 然后卸载node_modules文件进行重新下载&#xff0c;这时候有出现问题 自己的node版本太低。如…

【Node.js+koa--后端管理系统】设计动态发布、修改、查询、删除接口

&#x1f373;作者&#xff1a;贤蛋大眼萌&#xff0c;一名很普通但不想普通的程序媛\color{#FF0000}{贤蛋 大眼萌 &#xff0c;一名很普通但不想普通的程序媛}贤蛋大眼萌&#xff0c;一名很普通但不想普通的程序媛&#x1f933; &#x1f64a;语录&#xff1a;多一些不为什么的…

级联选择器(el-cascader)动态加载(lazyLoad)实现省市区三级选择

开开心心工作&#xff0c;兢兢业业生活 一、实现省市区级联选择&#xff08;插件&#xff09; 1. 需求&#xff1a;实现一个省市区的级联选择器&#xff0c;点击一级&#xff0c;动态加载下一级 那好&#xff0c;我们找个轮子 2. 他山之石&#xff08;找个轮子&#xff09; E…

Eclipse配置Tomcat详细教程,其中包含如何使用eclipse+tomcat创建并运行web项目

一&#xff1a;Tomcat的下载官网:Apache Tomcat - Welcome!https://tomcat.apache.org/ 进入官网显示如图所示的界面&#xff0c;在下下载的是Tomcat9.0版本&#xff0c;你可以自己选一款。 点击然后进入下面这个界面&#xff1a; 在下电脑是64位&#xff0c;所以 在下下载的6…

【vue】仿PC端微信制作聊天框

前言 采用(vuevue-routervuexes6stylus) 来实现一个仿PC端微信的小demo&#xff0c;可以使用一个智能api&#xff0c;实现智能对话。欢迎大家对鄙人提出宝贵意见&#xff0c;相互学习讨论&#xff0c;一起进步。 demo地址 源码地址 demo做的是PC版&#xff0c;建议使用电脑预…

我的VUE 学习之路(下)

前言&#xff1a; 在经历过前面在HTML下的VUE相关基础的洗礼后&#xff0c;我们可以动手去做一些事了&#xff0c;此时发现直接通过直接VUE组件方式与之前在HTML不同&#xff0c;首先要“静一静”&#xff0c;细看之下只是对之前的很多写法做了封装。 本文旨在直接上手Vue项目下…

FormData详解

FormData 接口提供了一种表示表单数据的键值对 key/value 的构造方式&#xff0c;并且可以轻松的将数据通过XMLHttpRequest.send() 方法发送出去&#xff0c;本接口和此方法都相当简单直接。如果表单 enctype 属性设为 multipart/form-data &#xff0c;则会使用表单的 submit(…

vue项目控制台报错信息问题记录:Uncaught TypeError: Cannot read properties of null (reading ‘setAttribute‘)

在写vue项目的时候&#xff0c;控制台总是报错如下代码&#xff1a; 1、Uncaught TypeError: Cannot read properties of null (reading ‘setAttribute‘) 主要是因为某些代码书写不规范&#xff0c;导致templete解析不出来&#xff0c;从而报错 解决方案&#xff1a; 检查下…

uniapp 实现生成海报并分享给微信好友和保存到本地相册

记录uniapp 生成二维码海报并保存到本地或者分享给微信好友 – 文章目录记录uniapp 生成二维码海报并保存到本地或者分享给微信好友前言一、引入生成二维码的组件二、点击右侧的分享图标生成海报三&#xff1a;将canvas 图片转化成图片&#xff08;最关键&#xff09;四&#…

el-tree设置利用setCheckedNodes/setCheckedKeys默认勾选节点,以及通过setChecked新增勾选指定节点

实现目标&#xff1a;在生成el-tree时&#xff0c;默认勾选其中某几个选项&#xff1b;或在进行某个选项的选中时&#xff0c;同时勾选上另一个选项。 实现效果&#xff1a; 在生成树结构时&#xff0c;默认勾选其中的两个选项。 在勾选其中一个选项时&#xff0c;另一个选项…

微前端之 qiankun 入门、上手、实战(构建大型 web 应用)

目录 前言 正文 一、介绍 微前端 qiankun 二、快速上手 ​☛主应用 ① 安装 qiankun ② 在主应用中注册微应用 ​☛微应用 ① 导出相应的生命周期钩子 ② 配置微应用的打包工具 三、项目实战 ​☛主应用 ① 安装 qiankun ② 注册微应用并启动 ③ 主应用添加…