[web教学] web前端文件上传可选择的4种方式

[复制链接]
查看1146 | 回复0 | 2023-8-23 11:56:22 | 显示全部楼层 |阅读模式 来自 中国北京
在web前端开辟中,文件上传属于很常见的功能,岂论是图片、还是文档等等资源,或多或少会有上传的需求。一样平常都是从添加文件开始,然后读取文件信息,再通过一定的方式将文件上传到服务器上,以供后续展示或下载使用。
本文将陈诉文件上传中所能用到的4种添加读取文件的方式:


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

起首先容的,就是最常用的html表单控件:input[type=file],它允许用户打开系统的文件选择框,选择相应文件后加载并读取到相干文件信息,它支持单个文件或多个文件,多文件选择增长属性:multiple。
input上传控件的欣赏器支持度最高,作为html的底子标签功能,不停都是web开辟中使用最多的一种文件上传方式。
它支持的重要属性:


  • multiple:允许用户选择多个文件举行添加
  • accept:指定文件上传时能担当的文件范例(MIME),如 image/png、image/*、video/* 等等
html控件代码如下,担当批量添加图片文件:
  1. <input id="fileInput" type="file" accept="image/*" multiple onchange="selectFile()" />
复制代码
以上代码添加了 onchange 事件,当选中不同文件时,可以获取到文件信息:
  1. const fileInput = document.getElementById('fileInput')
  2. function selectFile () {
  3.   const file = fileInput.files[0]
  4. }
复制代码
上面的js代码,就是监听事件的函数,通过元素对象,读取正在添加的文件信息。
大概也可以添加事件监听器,同样能读取到文件信息:
  1. document.getElementById('fileInput').addEventListener('change', (e) => {
  2.   const file = e.target.files[0]
  3. }, false)
复制代码
这里读取的上传控件元素对象的文件属性 files,它是 FileList 对象,一个针对 File 对象的聚集。
   文件信息是使用 File 对象API,用于吸收文件,具体的先容可见博文 详解前端二进制:Blob、File、FileReader、ArrayBuffer、TypeArray、DataView
  修改上传控件样式

input文件上传控件,之前被诟病比力多的就是样式太单一,在团体设计风格上会有很多范围,但我们可以使用css样式中的一个伪元向来美化该控件。
这个伪元素就是 ::file-selector-button,通过它可以对上传控件按钮举行颜色字体背景边框等举行各种样式设置。具体信息可见博文CSS伪元素详解以及伪元素与伪类的区别
  1. input::file-selector-button {
  2.   border: 1px solid #f00;
  3.   font-size: 20px;
  4.   border-radius: 5px;
  5.   background-color: azure;
  6. }
复制代码
以上代码,即通过伪元素对上传控件按钮举行了样式的修改,结果如下图。

固然,这个伪元素只能修改按钮的样式,至于上传控件的其他部门包括笔墨内容,无法修改,仍然会较影响设计,这时间我们就必要使用别的的方式,比如潜伏上传控件。
潜伏上传控件

我们只必要让上传控件潜伏不表现,但在点击的时间还能够触发上传控件的文件选择框,就能到达自界说各种好看样式的上传控件的目的。
潜伏上传控件的方式有很多种,下面先容此中一种,通过透明度的方式,先设置一个外部div元素,div内添加input上传元素,并设置透明度为0,到达不表现的目的,代码如下:
  1. <div class="input-container">
  2.   点击 <span style="color: red;">选择文件</span> 进行上传
  3.   <input class="input-file" type="file" name="file" multiple="multiple" />
  4. </div>
复制代码
  1. .input-container {
  2.   position: relative;
  3.   width: 250px;
  4.   margin: 20px 0;
  5. }
  6. .input-file {
  7.   position: absolute;
  8.   top: 0;
  9.   left: 0;
  10.   margin: 0;
  11.   opacity: 0;
  12. }
复制代码
以上代码,input上传控件元素通过绝对定位的方式置于div上层,透明度为0潜伏,视觉上只会表现底层div的内容(我们可自界说样式),但input控件会优先相应点击事件,这样就可以到达添加文件的目的。
固然,类似潜伏的方法尚有多种,基于css样式实现,可以设计出更多更好看的文件上传组件。
拖拽文件

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


  • dragenter:拖拽进入当前节点时触发
  • dragover:拖拽位于节点上方时,连续触发
  • drop:当拖拽至目的节点,释放时触发
我们只必要在页面上添加一个div元素标签,设置一定的区域大小,对这个元素的拖放事件举行监听即可:
  1. const dropArea = document.getElementById('dropArea')
  2. const stopPropagation = (e) => {
  3.   e.stopPropagation()
  4.   e.preventDefault()
  5. }
  6. dropArea.addEventListener('dragenter', stopPropagation, false)
  7. dropArea.addEventListener('dragover', stopPropagation, false)
  8. dropArea.addEventListener('drop', (dragEvent) => {
  9.   stopPropagation(dragEvent)
  10.   const file = dragEvent.dataTransfer.files[0]
  11. }, 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对象(见上文)。
有了这个事件和相应的属性,实现文件读取就比力方便了:
  1. document.getElementById('textarea').onpaste = (clipboardEvent) => {
  2.   clipboardEvent.stopPropagation()
  3.   clipboardEvent.stopImmediatePropagation()
  4.   
  5.   const { items, files } = clipboardEvent.clipboardData
  6.   if (files && files.length) {
  7.     const file = files[0]
  8.   }
  9. }
复制代码
以上代码,通过监听一个 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。
下面看一个具体的示例:
  1. <button id="openImageFile">打开图片</button>
复制代码
  1. document.getElementById('openImageFile').addEventListener('click', async () => {
  2.   const handle = await showOpenFilePicker({
  3.     multiple: true,
  4.     types: [{
  5.       description: '图片',
  6.       accept: { 'image/png': ['.jpg', '.png'] }
  7.     }]
  8.   })
  9.   if (handle && handle.length) {
  10.     const handleFile = handle[0]
  11.     const file = await handleFile.getFile()
  12.   }
  13. }, false)
复制代码
以上代码,通过按钮的click事件,使用showOpenFilePicker方法打开选择文件框,添加一个文件。
上传

读取到文件信息以后,就是将文件上传到服务器上,可以使用基本的上传方式,HTML表单:
  1. <form action="url" enctype="multipart/form-data" method="post">
  2.   <input name="fileInput" type="file" />
  3.   <button type="submit">提交</button>
  4. </form>
复制代码
以上代码,就是通过form表单,以 post 的方式将文件上传到 action 属性对应的url上传链接。
这种方式一样平常针对的就是input文件上传控件。
除了HTML表单的方式以外,我们还是可以使用 FormData 对象,构造一个表单数据,通过ajax等方式举行异步数据上传:
  1. const formData = new FormData()
  2. formData.append('file', file, file.name)
  3. const xhr = new XMLHttpRequest()
  4. xhr.open('POST', 'url', true)
  5. xhr.send(formData)
复制代码
以上代码,就是通过构造一个 formData 实例,添加文件数据,通过 xhr 的方式提交到对应的url上传链接。
构造 FormData 对象的方式,实用于以上4种文件读取方式,只要获取到文件信息,就可以通过这种方式上传到服务器。
总结

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

来源:https://blog.csdn.net/jimojianghu/article/details/127994785
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则