摘要:場景最近,小明遇到這樣一種情況在網頁中上傳文件時偶爾頁面會崩潰。小明仔細測試了這種情況,發現之前用的一個文件上傳組件有一點缺陷,于是,小明決定自己手寫一個,樣式如下圖一是沒有上傳文件時的樣式,圖二為上傳文件后的樣式。
場景
最近,小明遇到這樣一種情況:在網頁中上傳文件時偶爾頁面會崩潰。小明仔細測試了這種情況,發現之前用的一個文件上傳組件有一點缺陷,于是,小明決定自己手寫一個,樣式如下:
圖一是沒有上傳文件時的樣式,圖二為上傳文件后的樣式。虛線部分為放置區域,先來看代碼:
html部分css部分{{ fileName }}將文件拖拽至此,或
* { 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 // 清空,防止上傳后再上傳沒有反應 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事件
第一個要說的就是拖拽中的這兩個事件,因為這兩個事件撐起了拖拽上傳的核心功能。
對于拖拽這個動作而言,有二個核心概念,一個是拖拽元素,還一個是放置目標。這里,我只講放置目標上的事件,對于拖拽元素的事件,請自行查閱。
那對于放置目標,它有什么事件呢?如下:
當某個元素被拖動到一個有效的放置目標上(如上例中虛線區域)時,下列事件會依次發生:
(1) dragenter
(2) dragover
(3) dragleave 或 drop
只要有元素被拖動到放置目標上,就會觸發 dragenter 事件(類似于 mouseover 事件)。緊隨其后的是 dragover 事件,而且在被拖動的元素還在放置目標的范圍內移動時,就會持續觸發該事件。如果元素被拖出了放置目標,dragover 事件不再發生,但會觸發 dragleave 事件(類似于 mouseout事件)。如果元素被放到了放置目標中,則會觸發 drop 事件而不是 dragleave 事件。
對于本例來說,我們只需要關注dragover和drop事件。但是drop事件卻有點調皮,你想監聽它,還得進行一些處理,因為默認情況下,元素是不允許放置的,在拖動元素經過某些無效放置目標時,可以看到一種特殊的光標(圓環中有一條反斜線),表示不能放置。如下:
如果拖動元素經過不允許放置的元素,那無論用戶如何操作,都不會發生 drop 事件。那怎么辦呢?
我們可以重寫 dragover 事件的默認行為,如上例代碼中的e.preventDefault()。
細心的同學可能要問了,那drop事件中也有e.preventDefault(),去掉行不行呢?大家可以自行試下。
dataTransfer 對象
可能這個對象看著有些陌生,但是它的作用可不小。比如,你拖動一個圖片到目標區域,那目標區域怎么獲取這個圖片的信息呢?就靠它!它是事件對象的一個屬性,用于從被拖動元素向放置目標傳遞字符串格式的數據。在本例中,我們可以通過它來獲取拖動中的文件信息。
input的change事件
這個事件其實有坑的,它有這樣一個特性,即:上傳同一個文件,并不會觸發change事件,即使該文件內容做過修改。
細思極恐!比如,用戶要上傳一個文檔,但是拖拽到虛線區域后發現文檔內容還需要修改下,他改完后再拖拽該文檔,再提交到服務器,那么他上傳到服務器的文檔內容卻是未修改之前的!
所以,我們需要代碼e.target.value = ""來進行重置處理,這樣,每次上傳文件都會觸發change事件。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/101843.html
摘要:記錄下,開發需求是實現一個類似百度網盤全局拖拽的功能兼容瀏覽器,以上。監聽上的事件,顯示拖拽的蒙層監聽目標節點上的拖拽事件。 記錄下,開發需求是實現一個類似百度網盤全局拖拽的功能,兼容瀏覽器,IE0以上。實現思路是,采用原聲的拖拽事件。監聽window上的dragenter事件,拖拽目標節點是fixed罩住頁面的dropZone節點。 監聽window上的dragenter事件,顯示...
摘要:實現原理簡單,純技術處理圖片,幾乎不需要用到相關知識面向人群急于使用頭像裁剪組件的同學。裁剪框初始寬高上傳圖片后,裁剪區將預設為最大裁剪范圍。支持矩形裁剪目前九宮僅支持將圖片裁剪為正方形,不能裁剪為矩形,該功能將在后續優化。 項目簡介 本組件是vue下的頭像裁剪組件,可以直接拷貝代碼使用,無需安裝依賴 使用九宮格進行裁剪,自由選擇裁剪區域。 實時預覽裁剪后效果。 可以將裁剪好的圖片,...
摘要:常用的設置如下下的請求風格下的請求和不太一樣,在正式的請求發出之前都會先發一個類型為的請求作為試探,只有當該請求通過以后,正式的請求才能發向服務端。所以服務端路由我們還需要處理這樣一個請求注意該請求同樣需要設置跨域。 寫在前面 紅旗不倒,誓把JavaScript進行到底!今天介紹我的開源項目 Royal 里的圖片上傳組件的前后端實現原理(React + Node),花了一些時間,希望對...
摘要:更新歷史修復了無法導出中文文件的,增加了拖拽導入文件的功能。把編碼對象作為參數傳入,就可以生成一個可供下載的鏈接,下載的內容是完美的中文字符其他種類字符同樣支持,代碼如下保存為格式以上就是兩個關鍵新功能的實現原理。 Markcook 1.2 showImg(https://imgly.net/img/AhB.jpg); 項目地址:https://github.com/jrainlau...
閱讀 793·2021-11-11 16:54
閱讀 1528·2021-08-24 10:01
閱讀 1915·2019-08-30 15:54
閱讀 3300·2019-08-29 14:02
閱讀 3137·2019-08-28 18:22
閱讀 2249·2019-08-28 18:09
閱讀 3708·2019-08-26 10:26
閱讀 2673·2019-08-23 18:23