工作中寫了一個文件上傳的vue組件。本來只有點擊input選擇的功能,但是drag流行了起來,產品也要求加入拖拽上傳的功能,於是就遇到瞭如上所述的問題, ...
拖拽選擇文件
屏蔽預設事件
剛開始的時候,是在網上找了一個例子,這個例子中提到,需要在document上屏蔽和drag相關的所有事件的預設處理方式,代碼如下:
$(document).on({
dragleave:function(e){ //拖離
e.preventDefault();
},
drop:function(e){ //拖後放
e.preventDefault();
},
dragenter:function(e){ //拖進
e.preventDefault();
},
dragover:function(e){ //拖來拖去
e.preventDefault();
}
});
實際上,在我們的文件上傳中,接受拖拽的區域一般只有一個小區域,所以我對其做瞭如下的精簡
$drop.on("dragenter", function (e) {
e.preventDefault();
console.log("enter");
$drop.addClass("hover");
});
$drop.on("dragleave drop", function (e) {
e.preventDefault();
console.log("leave");
$drop.removeClass("hover");
});
$drop.on("dragover", function (e) {
e.preventDefault();
})
並且,在enter事件的時候,給目標區域增加了一個hover的樣式,讓接受區域高亮
預設情況下是醬紫的,(所以在drop 和leave事件中要去掉這個樣式)
對來源不同的文件進行處理
因為要同時處理input框和拖拽區域,所以我的html結構如下:
<div class="row" id="dropBox" @drop.prevent="Change($event)">
<div class="import-data">
<button
:class="{'disabled' : resultMsg.length > 0}"
class="btn btn-info">
<i class="fa fa-cloud-upload text"></i>
選擇文件
</button>
<span :class="{'error-tips':isError}">{{msg}}</span>
<input
type="file"
v-show="resultMsg.length == 0"
@change="Change($event)"
name="importExcel"
class="importExcel"
value="" />
</div>
<br>
<div class="loading" :style="'width:'+loading+'%'"></div>
</div>
為#dropBox
的drop事件和input
的change事件同時綁定Change
函數並將event對象傳入函數中
這裡,我在drop
事件上加入了prevent
修飾符來屏蔽預設事件,如果不屏蔽事件,接受區域#dropBox
是無法接收到文件,並且文件會觸發瀏覽器的下載(如果不能直接預覽的話)或者預覽;
Change:function(ev){
var e = window.event || ev;
var file = e.target.files ? e.target.files[0] : e.dataTransfer.files[0];
if(!file){
vm.msg = "點擊選擇,或者拖拽填寫好數據的excel文件致此";
vm.isError = true;
return false
}
},
ps:隱去了js代碼中的業務邏輯只講述公共部分,
在接受用戶選擇的文件時,用e.target.files
作為判斷條件,來判斷是否有input選擇的文件,如果是則取 e.target.files[0]
,如果不是 則取 e.dataTransfer.files[0]
。
這兩個事件對象的屬性是瀏覽器根據不同的情況掛在事件對象上的。
還有bug沒解決暫時收工 …………