JavaScript實(shí)現(xiàn)文件的拖拽上傳功能
1. 需求分析
文件上傳,可以說是我們在項(xiàng)目中最常用的功能之一。
文件上傳一般有兩種形式:點(diǎn)擊上傳和拖拽上傳。而上傳的內(nèi)容,又大體包括:文件和文件夾。
在項(xiàng)目中,我們一般都會直接選擇使用UI庫提供的上傳組件,簡單配置一下必要的屬性,就實(shí)現(xiàn)了文件上傳功能,至于組件底層實(shí)現(xiàn)的原理,是絲毫不知。
所以今天,針對文件和文件夾的拖拽上傳功能,我整理了一下具體的實(shí)現(xiàn),很簡單一起瞧瞧。
2. 問題實(shí)現(xiàn)
先普及一下元素拖拽的幾個(gè)API知識點(diǎn),再放上文件拖拽上傳的實(shí)現(xiàn)代碼,并做簡單的描述,最后做小結(jié)。
2.1 拖拽的6個(gè)API
元素拖拽的6個(gè)API分別是:dragenter、dragover、drop 以及 dragstart、drag、dragend。
ondragstart
事件:該事件在拖動操作開始時(shí)觸發(fā),即拖動操作的起點(diǎn)。通常在該事件的處理函數(shù)中設(shè)置拖動的數(shù)據(jù)和效果。
drag
事件:該事件在元素正在被拖動時(shí)持續(xù)觸發(fā),即在拖動過程中??梢栽谠撌录奶幚砗瘮?shù)中執(zhí)行一些實(shí)時(shí)的操作,例如更新元素的位置或顯示一些效果。
dragend
事件:該事件在拖動操作結(jié)束時(shí)觸發(fā),即拖動操作的終點(diǎn)。通常在該事件的處理函數(shù)中執(zhí)行一些清理操作或其他邏輯。
這三個(gè)事件通常用于控制拖動元素
起始、過程和結(jié)束階段的行為。
ondragenter
事件:該事件在拖動元素進(jìn)入目標(biāo)元素的范圍時(shí)觸發(fā)??梢栽谠撌录奶幚砗瘮?shù)中執(zhí)行一些顯示效果或狀態(tài)改變等操作。
ondragover
事件:該事件在拖動元素在目標(biāo)元素上移動時(shí)持續(xù)觸發(fā),即在拖動元素在目標(biāo)元素上懸停期間。通常需要阻止默認(rèn)的拖放行為,以便允許在目標(biāo)元素上釋放。
ondrop
事件:該事件在拖動元素在目標(biāo)元素上釋放時(shí)觸發(fā)??梢栽谠撌录奶幚砗瘮?shù)中獲取拖動的數(shù)據(jù)并執(zhí)行相應(yīng)的操作。
這三個(gè)事件通常用于控制目標(biāo)元素
在接受拖動元素時(shí)的行為。
2.2 文件拖拽上傳實(shí)現(xiàn)
元素拖拽的6個(gè)API,這里我們只需要使用dragover
、drop
這兩個(gè),就能實(shí)現(xiàn)文件拖拽上傳。
下面簡單描述一下實(shí)現(xiàn)過程,具體細(xì)節(jié)大家看代碼
就好,原理很簡單。
先獲取頁面中的 DropFrame 元素,再為其添加兩個(gè)事件監(jiān)聽器。
dragover
事件監(jiān)聽器:當(dāng)有元素拖拽到 DropFrame 區(qū)域時(shí)觸發(fā),用于指定拖放操作的效果。這里必須
阻止事件默認(rèn)行為,否則文件是拖不上去的,會被瀏覽器所阻止。
drop
事件監(jiān)聽器:當(dāng)在 DropFrame 區(qū)域釋放拖拽的元素時(shí)觸發(fā),用于處理拖放完成后的操作。內(nèi)部通過遍歷 e.dataTransfer.items
,判斷文件或文件夾,文件就直接獲取File對象,文件夾則遞歸獲取內(nèi)部文件的File對象,最后依次單獨(dú)上傳服務(wù)器。
完整實(shí)現(xiàn)代碼如下,復(fù)制即可使用。
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title></title> <style> #DropFrame { width: 360px; height: 120px; background-color: #b8deff; border: solid 1px #3470ff; } </style> </head> <body> <!-- 拖拽區(qū)域 --> <div id="DropFrame">文件拖到這里上傳</div> </body> <script> let dropFrame = document.getElementById('DropFrame'); // 拖動元素在目標(biāo)元素上懸停期間 dropFrame.addEventListener('dragover', (e) => { // 阻止默認(rèn)事件和冒泡 必須寫 e.stopPropagation(); e.preventDefault(); }); // 拖動元素在目標(biāo)元素上釋放時(shí)觸發(fā) dropFrame.addEventListener('drop', (e) => { // 阻止默認(rèn)事件和冒泡 必須寫 e.stopPropagation(); e.preventDefault(); // 文件上傳處理邏輯 let items = e.dataTransfer.items; for (const item of items) { // 提取Entry對象 const entry = item.webkitGetAsEntry(); if (entry.isFile) { // 處理文件,拿到File文件 entry.file((file) => { console.log(file, 'file'); // 上傳文件到服務(wù)器 // var formData = new FormData(); // formData.append('file', file); // axios.post('/upload', formData, {}) }) } else { // 處理文件夾,拿到FileEntry對象 const reader = entry.createReader() reader.readEntries((entries) => { reHandleFile(entries) }) } } }); // 如果文件夾是多級,則遞歸讀取 const reHandleFile = (entries) => { for (const entry of entries) { if (entry.isFile) { // 處理文件,拿到File文件 entry.file((file) => { console.log(file, 'file'); // 上傳文件到服務(wù)器 // var formData = new FormData(); // formData.append('file', file); // axios.post('/upload', formData, {}) }) } else { // 處理文件夾,拿到FileEntry對象 const reader = entry.createReader() reader.readEntries((entries) => { // 遞歸 reHandleFile(entries) }) } } } </script> </html>
2.3 小結(jié)
本文簡單介紹了,元素拖拽的6個(gè)API,以及文件拖拽上傳的實(shí)現(xiàn)過程。
元素拖拽的6個(gè)API,這里我們只需要使用dragover
、drop
這兩個(gè),就能實(shí)現(xiàn)文件拖拽上傳。
值得注意的是,必須
阻止事件默認(rèn)行為,否則文件是拖不上去的,會被瀏覽器所阻止。
結(jié)語
到此這篇關(guān)于JavaScript實(shí)現(xiàn)文件的拖拽上傳功能的文章就介紹到這了,更多相關(guān)JavaScript文件拖拽上傳內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 使用JavaScript輕松實(shí)現(xiàn)拖拽功能
- vue elementUi+sortable.js實(shí)現(xiàn)嵌套表格拖拽問題
- 淺析原生JavaScript中拖拽屬性draggable的使用
- vue結(jié)合el-table實(shí)現(xiàn)表格行拖拽排序(基于sortablejs)
- element-plus結(jié)合sortablejs實(shí)現(xiàn)table行拖拽效果
- 手把手教你用Javascript實(shí)現(xiàn)觀察者模式
- js觀察者模式的介紹及使用
- js觀察者模式的彈幕案例
- JavaScript設(shè)計(jì)模式之觀察者模式與發(fā)布訂閱模式詳解
- javascript設(shè)計(jì)模式 – 觀察者模式原理與用法實(shí)例分析
- JavaScript 拖拽與觀察者模式的實(shí)現(xiàn)及應(yīng)用小結(jié)
相關(guān)文章
js實(shí)現(xiàn)網(wǎng)頁隨機(jī)驗(yàn)證碼
這篇文章主要為大家詳細(xì)介紹了js實(shí)現(xiàn)網(wǎng)頁隨機(jī)驗(yàn)證碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-10-10微信小程序?qū)崿F(xiàn)發(fā)送驗(yàn)證碼按鈕效果
這篇文章主要為大家詳細(xì)介紹了微信小程序?qū)崿F(xiàn)發(fā)送驗(yàn)證碼按鈕效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-12-12JavaScript中的稀疏數(shù)組與密集數(shù)組[譯]
一般來說,JavaScript中的數(shù)組是稀疏的,也就是說,數(shù)組中的元素之間可以有空隙,因?yàn)橐粋€(gè)數(shù)組其實(shí)就是一個(gè)鍵值映射.本文解釋了如何創(chuàng)建稀疏數(shù)組和不稀疏的數(shù)組2012-09-09javascript函數(shù)定義的幾種區(qū)別小結(jié)
本篇文章主要是對javascript函數(shù)定義的幾種區(qū)別進(jìn)行了詳細(xì)的總結(jié)介紹,需要的朋友可以過來參考下,希望對大家有所幫助2014-01-01javascript 將共享屬性遷移到原型中去的實(shí)現(xiàn)方法
下面小編就為大家?guī)硪黄猨avascript 將共享屬性遷移到原型中去的實(shí)現(xiàn)方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-08-08Node.js:Windows7下搭建的Node.js服務(wù)(來玩玩服務(wù)器端的javascript吧,這可不是前端js插件
什么是Node.js?還服務(wù)器端javascript?對于這個(gè)概念我在這篇文章不做解釋,可以自己去搜索了解下,服務(wù)器端js不是新技術(shù),只是最近的node.js的火爆讓他爆發(fā)了,我會在以后的文章里解釋什么是node.js。2011-06-06