上一篇介紹了拖拽的基礎知識,這節我們談談拖拽的一些應用
HTML5不僅僅定義了拖拽的事件型別,還在事件物件中規範了一個重量級的物件:dataTransfer,藉助它,我們可以實現資料傳輸、拖拽圖案設定、拖拽檔案上傳,可通過event.dataTransfer來訪問該物件.
資料的傳輸
需要藉助event.dataTransfer
物件的一些方法實現。通過setData(dataType:string,data:string)
來設定待傳輸的資料,通過getData(dataType:string)
來獲取傳送的資料.可設定文字、html型別、url型別等。
步驟如下:
- dragstart ,設定資料
- drop,獲取並訪問資料。
let dragEle = document.querySelector('#drag-ele');
let dropTarget = document.querySelector('#drop-target');
dragEle.addEventListener('dragstart',event=>{
event.dataTransfer.setData('text/plain','i love you')
})
dropTarget .addEventListener('dragover',event=>{
//取消預設事件,啟用drop
event.preventDefault();
})
dropTarget .addEventListener('drop',event=>{
let data = event.dataTransfer.getData('text/plain');
console.log(data);// 'i love you'
})
複製程式碼
自定義拖拽效果
在拖拽過程中,瀏覽器預設了一些效果,可以通過設定dataTransfer的一些屬性或方法達到美觀效果。
指定一張圖片,在拖拽中跟隨滑鼠
dragstart階段配置:setDragImage(img:element,offsetX:number,offsetY:number)
let imgEle = document.querySelector('#img-ele')
dragEle.addEventListener('dragstart',event=>{
//計算圖片的高度和寬度的一半,作為x、y軸的偏移,使圖片居中
var offsetX = parseFloat(getComputedStyle(imgEle ).width)/2;
var offsetY = parseFloat(getComputedStyle(imgEle ).height)/2;
event.dataTransfer.setDragImage(imgEle ,offsetX,offsetY);
})
複製程式碼
小圖示提示
此處意義不是特別大,一般預設就行了。
允許釋放的型別(僅作為提示效果,並不做真正的限制).
- 首先設定拖動元素的允許效果(
effectAllowed
) - 其次設定釋放元素的釋放效果(
dropEffect
) - 允許效果應該在釋放效果之內:比如effectAllowed=copy,那麼dropEffect必須包含copy才行(可以為copy,也可為all表示包含所有)
dragEle.addEventListener('dragstart',event=>{
event.dataTransfer.effectAllowed = 'copy';//設定複製型別
})
dropTarget .addEventListener('dragover',event=>{
//取消預設事件,啟用drop
event.preventDefault();
})
dropTarget .addEventListener('drop',event=>{
event.dataTransfer.dropEffect = 'copy';//必須允許上面設定的copy型別
//設定為all允許所有,也是ok的。
})
複製程式碼
拖拽上傳檔案
拖拽上傳功能應該是最有用的了,本文使用formData上傳檔案。以express舉例說明。 與普通拖拽並無二致,可以從桌面、資源管理器中拖動檔案釋放到對應的元素上。
注意:
- 拖動檔案到瀏覽器中,瀏覽器會預設開啟該檔案,需要手動阻止該預設行為。在
dragover
、drop
中阻止預設行為:preventDefault. - drop後直接列印event.dataTransfer看到files屬性為空,但是直接訪問該屬性是可以拿到檔案內容的
dragTarget.addEventListener('dragover',event=>{
//阻止預設行為
event.preventDefault();
})
dragTarget.addEventListener('drop',event=>{
//阻止檔案開啟預設行為
event.preventDefault();
let file = event.dataTransfer.files[0];
var formData = new FormData();
formData.append('book',file);
var xhr = new XMLHttpRequest();
xhr.open('post','http://localhost:8080/profile');
xhr.send(formData)
})
複製程式碼
關於後端express的程式碼上傳到了github,如需要請自取。
總結
拖拽事件物件的dataTransfer物件,都是些實用的功能,不復雜,寫幾遍應該都能掌握。囿於水平有限,勘誤在所難免,望讀者朋友留言指正交流,謝謝啦!