上週提到了瀏覽器拖拉時會陸續觸發的幾個事件,我們知道了對可拖曳物件 (draggable) 進行拖曳與放開時以及拖曳物件滑過目標物件上方時,都會觸發對應的事件。今天我想研究看看在事件與事件之間可以做什麼事情,瀏覽器提供了 DragEvent 這個 API ,讓我們可以在開始拖曳時夾帶資料,並在拖曳結束放開時取得該筆資料。
Outline
- DataTransfer 物件
- 實際應用 DataTransfer API
DataTransfer 物件
上次有提到在瀏覽器操作中的拖曳功能,必須要自己搭配事件處理來實作,但其實有一些拖曳行為是預設就是有效,像是網頁連結和圖片的拖曳,以及文字選取的拖曳(反白)。而在這些以外的元素如果要觸發拖曳就必須使用 draggable
屬性來達成。
而在拖放事件的最一開始, ondragstart
事件被觸發時,我們其實可以利用事件物件(也就是事件回呼函式內的第一個參數 event
) 裡面的 dataTransfer
物件來賦予被拖放物件想要挾帶的資料,使用方式如下:
let dragger = document.querySelectAll('#dragger')
dragger.addEventListener("dragstart",function(e){
e.dataTransfer.setData('text/plain', 'This text may be dragged')
})
dataTransfer.setData
dataTransfer
物件負責處理拖曳行為之間的資料傳輸,這個物件裡面有兩個方法,分別是 setData
與 getData
, setData
使用方式如下:
dataTransfer.setData(format, data);
這個 API 有兩個參數,分別是:
- format :想要挾帶的資料格式,使用的是網頁常見的 MIME 格式字串,如文字格式就是
text/plain
,關於 MIME 型別可以參考 MDN 說明。 - data : 想要挾帶的資料
dataTransfer.getData
而在拖曳行為結束觸發 drop
事件時,則可以反過來利用 dataTransfer.getData
來取得前面挾帶的資料。
dataTransfer.getData(format);
記得必須透過同樣的格式字串來取得同一個參數。
DataTransfer.types
回傳在 ondragstart 時透過 setData API 所設定資料的資料格式,因為可能不會只設定一種格式的資料,所以會以陣列的方式來表示。
實際應用 Datatransfer API
接下來我們就試試看根據上面的說明,如何應用到實際的拖拉操作流程上,修改上次的範例來做說明,先做一個輸入框來設定拖曳時想要挾帶的數值。
let dragDataInput = document.querySelector('#dragDataInput')
<div class="row align-items-center">
<div class="col-2 d-flex align-items-center">
<p class="m-0">輸入想要挾帶的資料:</p>
</div>
<div class="col-10">
<input type="text" id="dragDataInput" class="form-control">
</div>
</div>
之後在原本的 dragststart
事件處理裡面,利用 dataTransfer 設定夾帶資料,這邊資料的格式就用字串做表示。
dragger.addEventListener("dragstart",function(e){
dragTemp = e.target
e.dataTransfer.setData('text/plain', dragDataInput.value)
})
後面一樣在 drop
事件就能夠透過 e.dataTransfer.setData
收到前面設定的資料了,我把它掛到拖曳完成的元素上。
dropper.addEventListener("drop",function(e){
...
let dragText = e.dataTransfer.getData('text/plain')
dragTemp.append(dragText)
e.target.style.color="#fff"
...
})
完整範例可以在這裡看到。
參考文章
https://developer.mozilla.org/zh-TW/docs/Web/API/HTML_Drag_and_Drop_API