HTML Drag and Drop API
HTML 拖放 介面使應用程式能夠在瀏覽器中使用拖放功能。
使用者可以使用滑鼠選擇可拖放的元素,將這些元素拖放到可放置的元素上,然後透過釋放滑鼠按鈕來放置它們。在拖動操作過程中,可拖放元素的半透明表示會跟隨指標移動。
您可以自定義哪些元素可以成為可拖放的,可拖放元素產生的反饋型別,以及可放置的元素。
此 HTML 拖放概述包括介面描述、嚮應用程式新增拖放支援的基本步驟,以及介面的互操作性摘要。
概念與用法
從表面上看,拖放實際上有三種不同的用例:在頁面內拖動元素、將資料從頁面拖出,以及將資料拖入頁面。它們在需求和實現上都有細微的差異。然而,拖放 API 提供了一個統一的模型來思考所有這些互動。
核心而言,拖動操作涉及三件事
- 要拖動的專案
- 要傳輸的底層資料
- 放置目標
並非所有這三項都一定在你的控制之下,或者需要你自己定義它們
- 當將外部資料拖入頁面時,沒有可拖動的專案需要定義(例如,可能是作業系統檔案瀏覽器中的檔案)。
- 當在頁面內拖動元素時,你通常不需要定義任何傳輸的資料;你只需要操作被拖動的元素。
- 當從頁面拖出時,沒有放置目標需要定義。
我們將看看每種如何定義和使用。
拖動事件
HTML 拖放使用DOM 事件模型和從滑鼠事件繼承的拖動事件。在拖動操作期間,會觸發多個事件型別,某些事件可能會觸發多次,例如drag和dragover事件。
| Event | 何時觸發... |
|---|---|
dragstart |
...可拖動的專案開始被拖動。 |
drag |
...可拖動的專案正在被拖動,每隔幾百毫秒。 |
dragenter |
...可拖動的專案進入該元素。 |
dragleave |
...可拖動的專案離開該元素。 |
dragover |
...可拖動的專案正在該元素上方拖動,每隔幾百毫秒。 |
drop |
...該元素是放置目標,並且可拖動的專案被放置在該元素上。 |
dragend |
...可拖動的專案停止被拖動。 |
注意: dragstart、drag和dragend事件在被拖動的專案上觸發,因此在從作業系統將檔案拖入瀏覽器時可能不會觸發。
同樣,dragenter、dragleave、dragover和drop事件在可能成為放置目標的元素上觸發,因此在將專案從瀏覽器拖出時可能不會觸發。
有關更多資訊,請參閱拖動操作。
可拖動的專案
在 HTML 中,影像、連結和選擇內容預設是可拖動的。要使任意元素可拖動,請將draggable屬性設定為"true"。
<p id="p1" draggable="true">This element is draggable.</p>
此時,該元素已經具有拖動外觀,儘管尚未定義任何行為
對於影像和連結,draggable預設為true,因此您只需將其設定為false即可停用這些元素的拖動。對於不可拖動的元素,“拖動”手勢通常會選擇文字。
注意: 當元素被設定為可拖動時,其內部的文字或其他元素將無法透過單擊和拖動滑鼠進行正常選擇。使用者必須按住Alt鍵才能用滑鼠選擇文字,或使用鍵盤。
選擇內容也是可拖動的。在這種情況下,源節點,即觸發dragstart和dragend等各種事件的節點,是拖動開始的文字節點。選擇內容可以部分或完全包含多個節點,包括文字節點和元素節點,這些節點都被視為同時被拖動。
如前所述,要拖動的專案也可以是網頁上不存在的內容——例如,作業系統檔案瀏覽器中的檔案。但是,只有網頁上的專案才能觸發dragstart和dragend事件。
有關更多資訊,請參閱拖動操作指南。
拖動資料儲存
您不能直接將 JavaScript 物件傳輸到任意網頁,更不用說傳輸到外部應用程式了,因此要將資料傳輸進出網頁,資料必須序列化為字串(或作為File)。在拖放中,此字串封裝在DataTransferItem物件中,該物件還定義了一個特定的type——通常是 MIME 型別,如text/html——該型別定義了字串應如何被解釋。
每個拖放操作都有一個相關的拖動資料儲存,它是一個DataTransfer物件,可以透過DragEvent的dataTransfer屬性訪問。對於預設可拖動的專案,如影像、連結和選擇內容,拖動資料已由瀏覽器定義;對於使用draggable屬性定義的自定義可拖動元素,您必須自己定義拖動資料。修改資料儲存的唯一時間是在dragstart處理程式中——對於任何其他拖動事件的dataTransfer,資料儲存是不可修改的。
setData()方法可用於向拖動資料新增專案,如下面的示例所示。
function dragstartHandler(ev) {
// Add different types of drag data
ev.dataTransfer.setData("text/plain", ev.target.innerText);
ev.dataTransfer.setData("text/html", ev.target.outerHTML);
ev.dataTransfer.setData(
"text/uri-list",
ev.target.ownerDocument.location.href,
);
}
const p1 = document.getElementById("p1");
p1.addEventListener("dragstart", dragstartHandler);
此外,除了dragstart事件之外,您唯一可以讀取資料儲存的時間是在drop事件期間(允許放置目標檢索資料)。對於所有其他事件,資料儲存無法訪問。
有關更多資訊,請閱讀處理拖動資料儲存。
放置目標
放置目標是使用者可以放置被拖動專案的元素。預設情況下,大多數元素都不是放置目標,如果您釋放拖動,會顯示“彈回”動畫,表示拖放失敗。任何元素都可以透過取消在其上觸發的dragover事件(使用preventDefault())來成為放置目標。
drop事件僅在放置目標上觸發,並且是您可以讀取拖動資料儲存的唯一時間。
以下示例顯示了一個最小有效放置目標,並結合了先前示例中的程式碼。
<p id="target">Drop Zone</p>
const target = document.getElementById("target");
// Cancel dragover so that drop can fire
target.addEventListener("dragover", (ev) => {
ev.preventDefault();
});
target.addEventListener("drop", (ev) => {
ev.preventDefault();
const data = ev.dataTransfer.getData("text/plain");
ev.target.append(data);
});
有關更多資訊,請參閱指定放置目標。
指南
介面
DragEvent-
傳遞給拖動事件處理程式的事件物件。
DataTransfer-
包含在上下文之間傳輸的任何資料,由文字項和檔案項組成。最初為拖放設計,現在也用於其他上下文,如剪貼簿 API。
DataTransferItem-
表示拖動資料儲存中的一項,可以是文字項或檔案項。
DataTransferItemList-
表示拖動資料儲存中
DataTransferItem物件的列表。
示例
每個介面的參考頁面也有單獨的示例。
規範
| 規範 |
|---|
| HTML |