记录一个常见的前端场景:给用户一个文件选择器,点击后能够从用户本地计算机抉择图片,也能够拖动图片至指定地位。并可显示图片预览,而后上传数据。
1. input元素
input html解说
应用type=’file’的<input>元素,容许用户从他们的设施中抉择一个或多个文件
例子:
<input type="file"
id="avatar"
multiple={false}
accept="image/png, image/jpeg"
>
属性
- multiple:布尔值,是否容许抉择多个文件
- accept:字符串,能够承受的文件类型
无论用户的设施或操作系统是什么,文件输出都提供一个按钮,关上一个容许用户抉择文件的文件抉择对话框。
办法
当用户抉择了一个文件后,如何获取到input元素拿到的文件呢?
<input type="file"
onChange={handleFileChange}
>
const handleFileChange = (e) => {
const files = e.target.files
}
- 定义input元素的onChange事件:通过event对象,拿到用户抉择的文件列表:e.target.files
它是蕴含一系列 File 对象的 FileList 对象。FileList 的行为像一个数组,能够通过查看 length 属性来取得已抉择文件的数量。
每个File对象蕴含以下属性:
{
name: "编组 3.png" //文件名
size: 1629 //文件大小
type: "image/png" //文件类型
lastModified: 1660545147281 //文件最新批改工夫 工夫戳
}
- Blob对象: Blob 对象示意一个不可变、原始数据的类文件对象。它的数据能够按文本或二进制的格局进行读取,也能够转换成 ReadableStream 来用于数据操作。
- File对象: 通常状况下, File 对象是来自用户在一个 <input> 元素上抉择文件后返回的 FileList 对象,也能够是来自在拖放操作生成的 DataTransfer 对象。
File 对象是非凡类型的 Blob。File 接口基于 Blob,继承了 blob 的性能并将其扩大以反对用户零碎上的文件。
自定义关上文件选择器的入口
默认款式
<input type='file' />
如果只是单纯的一个input元素,会渲染成默认的一个文件选择器的按钮:
为了好看,大部分状况须要暗藏这个‘抉择文件’按钮,自定义一个入口,比方对于抉择图片或视频
自定义
<div className={style.wrapper} onClick={click}>
<input type='file' ref={inputRef} className={style.input}/>
<div className={style.add} >
<Icon svg={IconAdd} className={style.addIcon} />
</div>
</div>
.input {
display: none;
}
const inputRef = useRef(null)
const click = () => {
inputRef.current && inputRef.current.click()
}
- 将input元素款式 display:none,暗藏input元素
- 点击父元素的事件处理器,调用input元素的click办法
成果: 点击这个区域,就会关上文件选择器。
2. 显示被抉择图片的缩略图
常常会有如下场景:用户点击上图+范畴后,呈现文件选择器 – 用户抉择了一张图片 – 该图片缩略图展现在页面上。(展现的缩略图能够是任意尺寸,可自定义)
其实就是如何将一个图片文件 转换成img元素的src,用于展现的问题。
咱们目前已知,从input元素拿到的图片文件是一个File对象,它会蕴含文件名等信息。那么该如何从中失去可用于<img/>
元素的src属性呢?
有以下两种办法:
2.1 FileReader读取文件内容
FileReader:
- FileReader 对象容许 Web 应用程序异步读取存储在用户计算机上的文件(或原始数据缓冲区)的内容。
- 应用 File 或 Blob 对象指定要读取的文件或数据。
- File 对象能够来自用户在一个<input>元素上抉择文件后返回的FileList对象,也能够来自拖放操作生成的 DataTransfer对象
用法:const reader = new window.FileReader()
失去一个fileReader对象
reader.result
一个属性,只读,示意读取到的文件内容。留神,该属性只在读取操作实现后才无效。读取失去的数据格式 取决于应用什么办法启动的读取操作。
reader.readAsDataURL(blob)
开始读取指定的Blob或File对象,当读取操作实现,result属性中将蕴含一个data: URL 格局的 Base64 字符串以示意所读取文件的内容。当咱们想在 src 中应用此数据,并将其用于 img 或其余标签时,能够用此办法。
// load事件,读取操作实现时触发。可在该处理函数中拿到读取后果 reader.result
reader.addEventListener('load', () => {
console.log('加载实现')
})
例子:
const [readFile, setReadFile] = useState(null)
const handleFileChange = (e) => {
const files = e.target.files
const file = files[0]
const reader = new window.FileReader()
reader.readAsDataURL(file)
reader.addEventListener('load', () => {
const result = reader.result
setReadFile(result)
})
}
return(
readFile && <img src={readFile} />
)
- handleFileChange 是input元素的onChange事件处理器
- 拿到文件列表,以第一个文件为例,创立一个reader读取器,并监听load事件,当读取实现,将后果作为img元素的src。 而后以URL的格局开始读取
- 后果就是,当文件读取实现,readFile就会有值,页面上就会呈现预览图片
file和fileReader
2.2 应用对象URL援用文件对象
URL.createObjectURL()
用法:
const url = window.URL.createObjectURL(file)
作用:
创立一个URL字符串,该字符串可能援用任何数据。也能够援用用户本地计算机的文件File对象。
因而应用对象URL也能够显示图片,只有将失去的url对象赋给img.src属性即可。
下图是打印出的file对象,和失去的对象URL。
3. 上传文件到服务器
在显示用户所抉择的文件缩略图后,如果有将图片上传到服务器的须要,就须要发送http申请。
发送http申请能够用XMLHttpRequest 或者 fetch API
3.1 XMLHttpRequest
XMLHttpRequest
在应用XMLHttpRequest发送文件数据时,个别先用 FormData 对象对图片文件做解决。
FormData 对象用来将数据编译成 键值对,以便用XMLHttpRequest来发送数据。
FormData
以图片为例:
const data = new window.FormData()
data.append('file', file) // file 就是一个file对象
const xhr = new XMLHttpRequest()
...
xhr.send(data)
参考链接:
全流程
发表回复