您好,登錄后才能下訂單哦!
這篇文章主要介紹JavaScript拖拽上傳功能如何實現(xiàn),文中介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們一定要看完!
最近,小明遇到這樣一種情況:在網(wǎng)頁中上傳文件時偶爾頁面會崩潰。小明仔細(xì)測試了這種情況,發(fā)現(xiàn)之前用的一個文件上傳組件有一點缺陷,于是,小明決定自己手寫一個,樣式如下:
圖一是沒有上傳文件時的樣式,圖二為上傳文件后的樣式。虛線部分為放置區(qū)域,先來看代碼:
html部分
<div id="app"> <div class="content"> <div class="drag-area" @dragover="fileDragover" @drop="fileDrop"> <div v-if="fileName" class="file-name">{{ fileName }}</div> <div v-else class="uploader-tips"> <span>將文件拖拽至此,或</span> <label for="fileInput" style="color: #11A8FF; cursor: pointer">點此上傳</label> </div> </div> </div> <div class="footer"> <input type="file" id="fileInput" @change="chooseUploadFile" style="display: none;"> <label for="fileInput" v-if="fileName" style="color: #11A8FF; cursor: pointer">選擇文件</label> <button @click="uploadOk">提交</button> </div> </div>
css部分
* { font-size: 14px; } .drag-area { height: 200px; width: 300px; border: dashed 1px gray; margin-bottom: 10px; color: #777; } .uploader-tips { text-align: center; height: 200px; line-height: 200px; } .file-name { text-align: center; height: 200px; line-height: 200px; }
js部分
new Vue({ el: '#app', data () { return { fileName: '', batchFile: '', MAX_FILE_SIZE: 10 * 1000 * 1000 } }, methods: { // 點擊上傳 chooseUploadFile (e) { const file = e.target.files.item(0) if (!file) return if (file.size > this.MAX_FILE_SIZE) { return alert('文件大小不能超過10M') } this.batchFile = file this.fileName = file.name // 清空,防止上傳后再上傳沒有反應(yīng) e.target.value = '' }, // 拖拽上傳 fileDragover (e) { e.preventDefault() }, fileDrop (e) { e.preventDefault() const file = e.dataTransfer.files[0] // 獲取到第一個上傳的文件對象 if (!file) return if (file.size > this.MAX_FILE_SIZE) { return alert('文件大小不能超過10M') } this.batchFile = file this.fileName = file.name }, // 提交 uploadOk () { if (this.batchFile === '') { return alert('請選擇要上傳的文件') } let data = new FormData() data.append('upfile', this.batchFile) // ajax } } })
核心原理說明
dragover和drop事件
第一個要說的就是拖拽中的這兩個事件,因為這兩個事件撐起了拖拽上傳的核心功能。
對于拖拽這個動作而言,有二個核心概念,一個是拖拽元素
,還一個是放置目標(biāo)
。這里,我只講放置目標(biāo)上的事件,對于拖拽元素的事件,請自行查閱。
那對于放置目標(biāo),它有什么事件呢?如下:
當(dāng)某個元素被拖動到一個有效的放置目標(biāo)上(如上例中虛線區(qū)域)時,下列事件會依次發(fā)生:
(1) dragenter
(2) dragover
(3) dragleave 或 drop
只要有元素被拖動到放置目標(biāo)上,就會觸發(fā) dragenter 事件(類似于 mouseover 事件)。緊隨其后的是 dragover 事件,而且在被拖動的元素還在放置目標(biāo)的范圍內(nèi)移動時,就會持續(xù)觸發(fā)該事件。如果元素被拖出了放置目標(biāo),dragover 事件不再發(fā)生,但會觸發(fā) dragleave 事件(類似于 mouseout事件)。如果元素被放到了放置目標(biāo)中,則會觸發(fā) drop 事件而不是 dragleave 事件。
對于本例來說,我們只需要關(guān)注dragover和drop事件。但是drop事件卻有點調(diào)皮,你想監(jiān)聽它,還得進(jìn)行一些處理,因為默認(rèn)情況下,元素是不允許放置的,在拖動元素經(jīng)過某些無效放置目標(biāo)時,可以看到一種特殊的光標(biāo)(圓環(huán)中有一條反斜線),表示不能放置。如下:
如果拖動元素經(jīng)過不允許放置的元素,那無論用戶如何操作,都不會發(fā)生 drop 事件。那怎么辦呢?
我們可以重寫 dragover 事件的默認(rèn)行為,如上例代碼中的e.preventDefault()。
細(xì)心的同學(xué)可能要問了,那drop事件中也有e.preventDefault(),去掉行不行呢?大家可以自行試下。
dataTransfer 對象
可能這個對象看著有些陌生,但是它的作用可不小。比如,你拖動一個圖片到目標(biāo)區(qū)域,那目標(biāo)區(qū)域怎么獲取這個圖片的信息呢?就靠它!它是事件對象的一個屬性,用于從被拖動元素向放置目標(biāo)傳遞字符串格式的數(shù)據(jù)。在本例中,我們可以通過它來獲取拖動中的文件信息。
input的change事件
這個事件其實有坑的,它有這樣一個特性,即:上傳同一個文件,并不會觸發(fā)change事件,即使該文件內(nèi)容做過修改。
細(xì)思極恐!比如,用戶要上傳一個文檔,但是拖拽到虛線區(qū)域后發(fā)現(xiàn)文檔內(nèi)容還需要修改下,他改完后再拖拽該文檔,再提交到服務(wù)器,那么他上傳到服務(wù)器的文檔內(nèi)容卻是未修改之前的!
所以,我們需要代碼e.target.value = ''來進(jìn)行重置處理,這樣,每次上傳文件都會觸發(fā)change事件。
以上是JavaScript拖拽上傳功能如何實現(xiàn)的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對大家有幫助,更多相關(guān)知識,歡迎關(guān)注億速云行業(yè)資訊頻道!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。