咱們在不少的項目場景當中,都會碰到須要上傳文件的狀況,相信大部分前端仔都對上傳的機制熟稔於心了,無非就是表單上傳,拖拽上傳等等,基本都是玩的溜溜的了。而今天咱們講的是其中鮮爲人知的一塊內容---經過拖拽的方式來上傳整個文件夾的內容~前端
咱們經過
<input type='file' multiple>
只能實現多文件的上傳,可是對於文件夾的上傳依舊是一籌莫展web
既然講的是拖拽上傳文件夾,那麼咱們天然從咱們的拖拽的事件對象講起了。數組
咱們來看一下MDN對dataTransfer
對象的描述: DataTransfer
被用於承載拖拽和拖放時的數據,它能夠承載多個數據項。服務器
注意:當咱們的拖放動做解釋並完成回調函數以後,dataTransfer中的數據項就會被清理回收,若是咱們在拖拽的過程須要作一些額外的判斷或者在回調外進行操做時,須要強引用這些數據項的內容,防止其被垃圾回收機制給回收掉。markdown
DataTransfer.files
: 這個屬性就是一個文件僞數組,用來存儲拖拽對象的文件屬性,若是拖拽的不是文件,那麼這個數組爲空。 DataTransfer.items
該屬性就是咱們此次的關注重點,數據選項,爲何這麼說,由於這個數據項支持文件的讀取,而其特有的文件的屬性以及最爲重要的entry
對象是咱們實現文件夾上傳的重中之重。 DataTransfer.getData/DataTransfer.setData
這個API是DataTransfer
比較重要的一個屬性,他能夠自由的設置和讀取屬性。着就給咱們進行組件的拖拽創造了無限的可能。通常咱們都是經過源組件的dragstart
事件調用DataTransfer.setData()
傳入數據,而後在目的組件當中經過DataTransfer.getData()
來獲取數據進行相關操做。app
注意:這兩個API沒法直接傳入對象,建議經過JSON序列化和反序列化的手段來進行對象的傳遞。ide
因爲DataTransfer
含有大量額外的接口以及屬性咱們就不展開討論,有興趣的童鞋能夠去MDN自行閱讀,說不定就能找到知足你業務需求的接口哦~函數
DataTransfer.items
是一個DataTransferItemList
對象,這個對象一樣的也是一個僞數組,它含有length
屬性。每個數組成員都是一個DataTransferItem
對象。咱們的拖拽文件夾操做就是須要依靠這個對象來實現的。ui
咱們接着着重來看這個對象。lua
這個API就是咱們引出下一個關鍵對象的入口,這個是一個非標準的API看他的函數名咱們也能夠知道是支持webkit的一個API。這個API是幹什麼的?咱們來看一下MDN官方的解釋(本人翻譯,建議能夠看原版英文): 若是DataTransferItem
承載的是一個文件數據,那麼咱們能夠用調用該API來建立一個FileSystemFileEntry
或者FileSystemDirectoryEntry
對象。望文生義,很顯然咱們能夠經過這兩個對象來區分咱們拖拽的是文件仍是文件夾。這兩個對象都是經過FileSystemEntry
接口擴展的 這個兩個對象同時都擁有isFile
和isDirectory
屬性用來描述這個對象是文件仍是文件夾。咱們能夠判斷這兩個屬性從而進一步進行操做。 FileSystemEntry.fullPath
這個屬性是用來保存徹底路徑的,根目錄就是最初拖拽的文件夾路徑。咱們後續上傳服務器就會用到這個屬性。
注意:接下來大部分的API都是非標準的API,在後續可能有變化,若是須要在公司業務使用,建議標註清楚使用事項和注意事項。
FileSystemFileEntry.file()
函數用來實際讀取文件內容,該函數能夠註冊兩個回調函數,一個成功回調,一個失敗錯誤回調。在成功回調中,會把真正的file對象傳入進來,而後後面作什麼事,就不言而喻了吧~ FileSystemDirectoryEntry.createReader()
這個API用來實現建立一個FileSystemDirectoryReader
API用來讀取文件夾中的FileSystemFileEntry
對象了。和FileSystemFileEntry.file()
用法同樣,也是在FileSystemDirectoryReader.readEntries
中註冊成功回調,而後在回調中傳入實際的entries數組。到了這裏咱們差很少也就瞭解了整個的相關API的狀況了,那麼接下來就是遞歸遍歷文件夾的工做了,代碼就不寫了邏輯也不是特別難。到此結束