詳解javascript拖拽(二)拖拽的應用及示例

AndyLaw發表於2018-12-24

上一篇介紹了拖拽的基礎知識,這節我們談談拖拽的一些應用

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舉例說明。 與普通拖拽並無二致,可以從桌面、資源管理器中拖動檔案釋放到對應的元素上。

注意:

  • 拖動檔案到瀏覽器中,瀏覽器會預設開啟該檔案,需要手動阻止該預設行為。在dragoverdrop中阻止預設行為: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物件,都是些實用的功能,不復雜,寫幾遍應該都能掌握。囿於水平有限,勘誤在所難免,望讀者朋友留言指正交流,謝謝啦!

相關文章