上傳檔案功能可以說是專案經常出現的需求。從在社群媒體上傳照片到在求職網站上發布履歷,文件上傳無所不在。在本文中,我們將討論 HTML檔案上傳支援的10種用法,希望對你有用。
1. 單一檔案上傳
我們可以將input
類型指定為file
,以在網路應用程式中使用檔案上傳功能。
<input type="file" id="file-uploader">
input filte
提供按鈕上傳一個或多個檔案。預設情況下,它使用作業系統的本機檔案瀏覽器上傳單一檔案。成功上傳後,File API
使得可以使用簡單的 JS 程式碼讀取File
物件。要讀取File
對象,我們需要監聽 change
事件。
首先,透過id
取得檔案上傳的實例:
const fileUploader = document.getElementById('file-uploader');
然後新增一個change
事件偵聽器,以便在上傳完成後讀取取文件對象, 我們從event.target.files
屬性取得上傳的文件資訊:
fileUploader.addEventListener('change', (event) => { const files = event.target.files; console.log('files', files); });
在控制台中觀察輸出結果,這裡關註一下FileList
陣列和File
對象,該對象具有有關上傳文件的所有元資料資訊。
如果大家看到這裡,有點激動,想手賤一下,可以CodePen 玩玩,地址:https://codepen.io/atapas/pen /rNLOyRm
2. 多文件上傳
如果我們想要上傳多個文件,需要在標籤上新增multiple
屬性:
<input type="file" id="file-uploader" multiple />
現在,我們可以上傳多個文件了,以前面事例為基礎,選擇多個文件上傳後,觀察一下控制台的變化:
##如果大家看到這裡,有點激動,想手賤一下,可以CodePen 玩玩,網址:https://codepen.io/atapas/pen/MWeamYp3.了解檔元資料每當我們上傳檔案時,
File物件都有元資料訊息,例如
file name,
size,last update time,type 等等。這些資訊對於進一步的驗證和特殊處理很有用。
const fileUploader = document.getElementById('file-uploader'); // 听更 change 件并读取元数据 fileUploader.addEventListener('change', (event) => { // 获取文件列表数组 const files = event.target.files; // 遍历并获取元数据 for (const file of files) { const name = file.name; const type = file.type ? file.type: 'NA'; const size = file.size; const lastModified = file.lastModified; console.log({ file, name, type, size, lastModified }); } });下面是單一檔案上傳的輸出結果:
#如果大家看到這裡,有點激動,想手賤一下,可以CodePen玩玩,地址:https://codepen.io/atapas/pen/gOMaRJv#4.了解
accept 屬性
我們可以使用 accept屬性來限制要上載的檔案的類型,如果只想上傳的檔案格式是
.jpg,
.png 時,可以這麼做:
<input type="file" id="file-uploader" accept=".jpg, .png" multiple>在上面的程式碼中,只能選擇後綴是
.jpg和
.png的檔案。
如果大家看到這裡,有點激動,想手賤一下,可以CodePen 玩玩,地址:https://codepen.io/atapas/pen/OJXymRP#5. 管理文件內容成功上傳文件後顯示文件內容,站在使用者的角度上,如果上傳之後,沒有一個預覽的,就很奇怪也不體貼。 我們可以使用
FileReader物件將檔案轉換為二進位字串。然後新增
load 事件偵聽器,以在成功上傳檔案時取得二進位字串。
// FileReader 实例 const reader = new FileReader(); fileUploader.addEventListener('change', (event) => { const files = event.target.files; const file = files[0]; reader.readAsDataURL(file); reader.addEventListener('load', (event) => { const img = document.createElement('img'); imageGrid.appendChild(img); img.src = event.target.result; img.alt = file.name; }); });
如果大家看到這裡,有點激動,想手賤一下,可以CodePen 玩,地址:https://codepen.io/atapas/pen/zYBvdjZ#6.驗證檔案大小如果使用者上傳圖片過大,為了不讓伺服器有壓力,我們需要限制圖片的大小,下面是允許使用者上傳小於
1M 的圖片,如果大於
1M 將上傳失敗。
fileUploader.addEventListener('change', (event) => { // Read the file size const file = event.target.files[0]; const size = file.size; let msg = ''; // 检查文件大小是否大于1MB if (size > 1024 * 1024) { msg = `<span style="color:red;">The allowed file size is 1MB. The file you are trying to upload is of ${returnFileSize(size)}</span>`; } else { msg = `<span style="color:green;"> A ${returnFileSize(size)} file has been uploaded successfully. </span>`; } feedback.innerHTML = msg; });
如果大家看到這裡,有點激動,想手賤一下,可以CodePen 玩,地址:https://codepen.io/atapas/pen/pobjMKv#7. 顯示檔案上傳進度更好的使用者體驗是讓使用者知道檔案上傳進度,前面我們用過了
FileReader以及讀取和載入檔案的事件。
const reader = new FileReader();
FileReader還有一個
progress 事件,表示目前上傳進度,配合HTML5的
progress標籤,我們來模擬一下檔案的上傳進度。
reader.addEventListener('progress', (event) => { if (event.loaded && event.total) { // 计算完成百分比 const percent = (event.loaded / event.total) * 100; // 将值绑定到 `progress`标签 progress.value = percent; } });
如果大家看到这里,有点激动,想手贱一下,可以 CodePen 玩玩,地址:https://codepen.io/atapas/pen/eYzpwYj
8. 怎么上传目录上传?
我们可以上传整个目录吗?嗯,这是可能的,但有一些限制。有一个叫做webkitdirectory
的非标准属性(目前只有谷歌浏览器还有Microsoft Edge支持按照文件夹进行上传),它允许我们上传整个目录。
目前只有谷歌浏览器还有Microsoft Edge支持按照文件夹进行上传,具体可以看下百度云盘的网页版的上传按钮,在火狐下就支持按照文件进行上传,而在谷歌和Edge下,就会给用户提供一个下拉,让用户选择是根据文件进行上传还是根据文件夹进行上传。
<input type="file" id="file-uploader" webkitdirectory />
用户必须需要确认才能上传目录
用户单击“上传”按钮后,就会进行上传。 这里要注意的重要一点。 FileList
数组将以平面结构的形式包含有关上载目录中所有文件的信息。 对于每个File
对象,webkitRelativePath
属性表示目录路径。
例如,上传一个主目录及其下的其他文件夹和文件:
现在,File 对象将将webkitRelativePath
填充为:
如果大家看到这里,有点激动,想手贱一下,可以 CodePen 玩玩,地址:https://codepen.io/atapas/pen/dyXYRKp
9. 拖拽上传
不支持文件上传的拖拽就有点 low 了,不是吗?我们来看看如何通过几个简单的步骤实现这一点。
首先,创建一个拖放区域和一个可选的区域来显示上传的文件内容。
<div id="container"> <h1>Drag & Drop an Image</h1> <div id="drop-zone"> DROP HERE </div> <div id="content"> Your image to appear here.. </div> </div>
通过它们各自的ID获取dropzone
和content
区域。
const dropZone = document.getElementById('drop-zone'); const content = document.getElementById('content');
添加一个dragover
事件处理程序,以显示将要复制的内容的效果:
dropZone.addEventListener('dragover', event => { event.stopPropagation(); event.preventDefault(); event.dataTransfer.dropEffect = 'copy'; });
接下来,我们需要一个drop
事件监听器来处理。
dropZone.addEventListener('drop', event => { // Get the files const files = event.dataTransfer.files; });
如果大家看到这里,有点激动,想手贱一下,可以 CodePen 玩玩,地址:https://codepen.io/atapas/pen/ExyVoXN
10. 使用objectURL
处理文件
有一个特殊的方法叫做URL.createobjecturl()
,用于从文件中创建唯一的URL。还可以使用URL.revokeObjectURL()
方法来释放它。
URL.revokeObjectURL()
静态方法用来释放一个之前已经存在的、通过调用URL.createObjectURL()
创建的 URL 对象。当你结束使用某个 URL 对象之后,应该通过调用这个方法来让浏览器知道不用在内存中继续保留对这个文件的引用了。
fileUploader.addEventListener('change', (event) => { const files = event.target.files; const file = files[0]; const img = document.createElement('img'); imageGrid.appendChild(img); img.src = URL.createObjectURL(file); img.alt = file.name; });
如果大家看到这里,有点激动,想手贱一下,可以 CodePen 玩玩,地址:https://codepen.io/atapas/pen/BazzaoN
总结
无论何时,如果你还想学习本文涉及的一些知识,你可以在这里尝试。
英文原文地址:https://dev.to/atapas/10-useful-file-upload-tips-for-web-developers-2d1d
作者: Tapas Adhikary
译者:前端小智
更多编程相关知识,请访问:编程入门!!