摘要:此文研究中的拖放接口,提供各個(gè)屬性和方法的說明,解決拖放過程中的拖拽數(shù)據(jù)對(duì)象存儲(chǔ)和獲取問題。方法增加一個(gè)拖拽數(shù)據(jù)對(duì)象到屬性中,并返回增加的拖拽數(shù)據(jù)對(duì)象。若拖拽數(shù)據(jù)對(duì)象是文本字符串類型,通過回調(diào)函數(shù)獲取拖拽數(shù)據(jù)中的字符串?dāng)?shù)據(jù)。
此文研究Web API中的拖放接口,提供各個(gè)屬性和方法的說明,解決拖放過程中的拖拽數(shù)據(jù)對(duì)象存儲(chǔ)和獲取問題。
拖放API作用到兩個(gè)目標(biāo)對(duì)象,分別是拖拽目標(biāo)對(duì)象和放置目標(biāo)對(duì)象。
拖拽目標(biāo)一個(gè)設(shè)置draggable屬性的值為trueDOM元素或者一個(gè)選中狀態(tài)的文本區(qū)塊可以成為拖拽目標(biāo)。
OR
一個(gè)綁定了下圖放置目標(biāo)對(duì)應(yīng)的5個(gè)事件的DOM元素可以成為放置目標(biāo)。
事件拖放API有8個(gè)事件,其中有3個(gè)事件綁定在拖拽目標(biāo)上,有5個(gè)事件綁定在放置目標(biāo)上。
綁定在拖拽目標(biāo)Evnet | Description |
---|---|
dragstart | 當(dāng)用戶開始拖拽一個(gè)元素或者一個(gè)文本選取區(qū)塊的時(shí)觸發(fā)。 |
drag | 當(dāng)用戶正在拖拽一個(gè)元素或者一個(gè)文本選取區(qū)塊的時(shí)觸發(fā)。 |
dragend | 當(dāng)用戶結(jié)束拖拽一個(gè)元素或者一個(gè)文本選取區(qū)塊的時(shí)觸發(fā)。(如放開鼠標(biāo)按鍵或按下鍵盤的 escap 鍵) |
Event | Description |
---|---|
dragenter | 當(dāng)一個(gè)元素或文字選取區(qū)塊被拖曳移動(dòng)進(jìn)入一個(gè)有效的放置目標(biāo)時(shí)觸發(fā)。 |
dragover | 當(dāng)一個(gè)元素或文字選取區(qū)塊被拖曳移動(dòng)經(jīng)過一個(gè)有效的放置目標(biāo)時(shí)觸發(fā)。 |
dragleave | 當(dāng)一個(gè)元素或文字選取區(qū)塊被拖曳移動(dòng)離開一個(gè)有效的放置目標(biāo)時(shí)觸發(fā)。 |
dragexist | 當(dāng)一個(gè)元素不再是被選取中的拖曳元素時(shí)觸發(fā)。(Firefox能觸發(fā),觸發(fā)順序:dragexist->dragleave->drop;Chrome無法觸發(fā)) |
drop | 當(dāng)一個(gè)元素或文字選取區(qū)塊被放置至一個(gè)有效的放置目標(biāo)時(shí)觸發(fā)。 |
通過下圖能更直觀觀察每個(gè)事件觸發(fā)的時(shí)機(jī)
戳我看源碼
DataTransfer對(duì)象注意:在dragover事件中使用event.preventDefault();阻止默認(rèn)事件,才能觸發(fā)drop事件
在進(jìn)行拖放操作時(shí),會(huì)觸發(fā)上面所述的8個(gè)事件,每個(gè)event事件對(duì)象中都會(huì)有DataTransfer對(duì)象用來保存被拖動(dòng)的數(shù)據(jù)。它可以保存一項(xiàng)或多項(xiàng)數(shù)據(jù)、一種或者多種數(shù)據(jù)類型。
effectAllowed用來指定拖動(dòng)時(shí)被允許的效果。
在dragstart事件中設(shè)置
屬性 dropEffect設(shè)置實(shí)際的放置效果,它應(yīng)該始終設(shè)置成effectAllowed的可能值之一 。
在dragenter事件和dragover事件中設(shè)置
effectAllowed和dropEffect屬性的栗子:戳我看源碼
files包含一個(gè)在數(shù)據(jù)傳輸上所有可用的本地文件列表。如果拖動(dòng)操作不涉及拖動(dòng)文件,此屬性是一個(gè)空列表。
filesZoneEl.addEventListener("drop", (event) => { event.preventDefault(); let files = event.dataTransfer.files; for (let i = 0, len = files.length; i < len; i++) { let liEl = document.createElement("li"); liEl.innerHTML = files[i].name; filesListEl.appendChild(liEl); } });
戳我看源碼
types保存一個(gè)被存儲(chǔ)數(shù)據(jù)的類型列表作為第一項(xiàng),順序與被添加數(shù)據(jù)的順序一致。如果沒有添加數(shù)據(jù)將返回一個(gè)空列表。
items存儲(chǔ)DataTransferItem數(shù)據(jù)對(duì)象的列表。
方法 addElement()設(shè)置拖動(dòng)源。
event.dataTransfer.addElement(element);setData()
為一個(gè)給定的類型設(shè)置數(shù)據(jù)并存儲(chǔ)在items屬性中。
getData()從items屬性中獲取給定類型的數(shù)據(jù),無數(shù)據(jù)時(shí)返回空字符串。
event.dataTransfer.getData(type);clearData()
從items屬性中刪除與給定類型關(guān)聯(lián)的數(shù)據(jù),若類型為空則刪除所有數(shù)據(jù)。
event.dataTransfer.clearData(type);setDragImage()
自定義一個(gè)期望的拖動(dòng)時(shí)的圖片,默認(rèn)為被拖動(dòng)的節(jié)點(diǎn)。
event.dataTransfer.setDragImage(imgElement, offsetX, offsetY);
Param | Description |
---|---|
imgElement | 要用作拖動(dòng)反饋圖像元素。 |
offsetX | 圖像內(nèi)的水平偏移量。 |
offsetY | 圖像內(nèi)的垂直偏移量。 |
設(shè)置拖動(dòng)時(shí)的圖片時(shí),要把圖片預(yù)加載,否則圖片會(huì)在拖動(dòng)開始dragstart事件觸發(fā)時(shí)才會(huì)加載圖片,會(huì)導(dǎo)致拖動(dòng)圖出不來或閃一下的后果。可把圖片放到標(biāo)簽并設(shè)置display:none;,原理詳看我之前的文章Web圖片資源的加載與渲染時(shí)機(jī)。
DataTransferItemListdataTramsfer對(duì)象的items屬性,包含了一系列DataTransferItem拖拽數(shù)據(jù)對(duì)象。
屬性 length數(shù)組長度。
方法 add()增加一個(gè)拖拽數(shù)據(jù)對(duì)象到items屬性中,并返回增加的拖拽數(shù)據(jù)對(duì)象。
event.dataTransfer.items.add(file);remove()
從items屬性中移除指定位置的一個(gè)拖拽數(shù)據(jù)對(duì)象。
event.dataTransfer.items.remove(index);clear()
清空items屬性中的所拖拽數(shù)據(jù)對(duì)象。
event.dataTransfer.items.clear();DataTransferItem
DataTransferItemList列表中的拖拽數(shù)據(jù)對(duì)象。
屬性 kind拖拽數(shù)據(jù)對(duì)象類型。
Value | Description |
---|---|
file | 文件類型。 |
string | 文本字符串類型。 |
MIME類型的Unicode字符串,例如text/plain、text/html或image/png。
方法 getAsFile()若拖拽數(shù)據(jù)對(duì)象是文件類型,則返回一個(gè)文件對(duì)象。
let itemList = event.dataTransfer.items; for (let i = 0, len = itemList.length; i < len; i++) { if (itemList[i].kind == "file") { console.log(itemList[i].getAsFile()); } }getAsString()
若拖拽數(shù)據(jù)對(duì)象是文本字符串類型,通過回調(diào)函數(shù)獲取拖拽數(shù)據(jù)中的字符串?dāng)?shù)據(jù)。
let itemList = event.dataTransfer.items; for (let i = 0, len = itemList.length; i < len; i++) { if (itemList[i].kind == "string") { itemList[i].getAsString((data) => { console.log(data); }); } }拖放對(duì)象的數(shù)據(jù)存儲(chǔ)
在進(jìn)行拖放操作時(shí),有可能需要把拖拽目標(biāo)的數(shù)據(jù)傳送給放置目標(biāo),此時(shí)一般操作是在dragstart事件觸發(fā)時(shí)把需要的數(shù)據(jù)存儲(chǔ)到一個(gè)變量,然后再drop事件觸發(fā)時(shí)獲取這個(gè)變量。但當(dāng)dragstart事件和drop事件在不同的文件定義,又不想玷污全局變量的情況下,我們需要更好的辦法來存儲(chǔ)拖放數(shù)據(jù)。
在DataTransfer對(duì)象中的items屬性就是用來存儲(chǔ)拖放數(shù)據(jù)的,數(shù)據(jù)類型分為文本類型和文件類型。
存儲(chǔ)文本字符串類型數(shù)據(jù):event.dataTransfer.setData(type, data);
OR
event.dataTransfer.items.add(data, type);
存儲(chǔ)文件類型數(shù)據(jù):一種文本字符串類型只能存儲(chǔ)一個(gè)數(shù)據(jù),當(dāng)重復(fù)文本字符串類型存儲(chǔ)數(shù)據(jù)時(shí),后者會(huì)覆蓋前者。
event.dataTransfer.items.add(file);獲取所有文本字符串類型的拖拽數(shù)據(jù)對(duì)象
event.dataTransfer.types獲取所有文件類型的拖拽數(shù)據(jù)對(duì)象
let files = event.dataTransfer.files; for (let i = 0, len = files.length; i < len; i++) { console.log(files[i]); }
OR
let itemList = event.dataTransfer.items; for (let i = 0, len = itemList.length; i < len; i++) { if (itemList[i].kind == "file") { console.log(itemList[i].getAsFile()); } }獲取所有文本字符串類型的拖拽數(shù)據(jù)對(duì)象
let itemList = event.dataTransfer.items; for (let i = 0, len = itemList.length; i < len; i++) { if (itemList[i].kind == "string") { itemList[i].getAsString((data) => { console.log(data); }); } }獲取指定文本字符串類型的拖拽數(shù)據(jù)對(duì)象
event.dataTransfer.getData(type);刪除指定文本字符串類型的拖拽數(shù)據(jù)對(duì)象
event.dataTransfer.clearData(type);刪除指定位置的拖拽數(shù)據(jù)對(duì)象
event.dataTransfer.items.remove(index);清空所有拖拽數(shù)據(jù)對(duì)象
event.dataTransfer.clearData();
OR
event.dataTransfer.items.clear();栗子
上面的幾個(gè)栗子都使用了以上方法存儲(chǔ)和獲取拖拽數(shù)據(jù)對(duì)象,感興趣的可以看看源碼。
歡迎關(guān)注:Leechikit
原文鏈接:segmentfault.com到此本文結(jié)束,歡迎提問和指正。
寫原創(chuàng)文章不易,若本文對(duì)你有幫助,請(qǐng)點(diǎn)贊、推薦和關(guān)注作者支持。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/87096.html
摘要:注意點(diǎn)在鼠標(biāo)操作拖放期間,有一些事件可能觸發(fā)多次,比如和。可拖拽元素,建議使用,設(shè)定可拖拽元素的鼠標(biāo)游標(biāo),提升交互。在中使用拖拽中使用可以直接綁定到組件上。 什么是 Drag and Drop (拖放)? 簡單來說,HTML5 提供了 Drag and Drop API,允許用戶用鼠標(biāo)選中一個(gè)可拖動(dòng)元素,移動(dòng)鼠標(biāo)拖放到一個(gè)可放置到元素的過程。 我相信每個(gè)人都或多或少接觸過拖放,比如瀏覽...
閱讀 2133·2021-11-22 15:24
閱讀 2428·2021-09-09 11:53
閱讀 3047·2021-09-04 16:40
閱讀 1646·2019-08-30 15:52
閱讀 3366·2019-08-29 13:47
閱讀 2747·2019-08-26 17:40
閱讀 1554·2019-08-26 13:24
閱讀 2255·2019-08-26 12:01