You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: files/en-us/web/api/html_drag_and_drop_api/drag_data_store/index.md
+4-5Lines changed: 4 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -10,19 +10,19 @@ The {{domxref("DragEvent")}} interface has a {{domxref("DragEvent.dataTransfer",
10
10
11
11
## DataTransfer, DataTransferItem, and DataTransferItemList
12
12
13
-
Fundamentally, the drag data store is a list of items, represented as a {{domxref("DataTransferItemList")}} of {{domxref("DataTransferItem")}} objects. Generally, it _does not_ represent multiple resources being transferred, but the same resource encoded in different ways, so that the receiving end can choose the most appropriate supported interpretation. The items are intended to be sorted in descending order of preference. Each item can be one of two [kinds](/en-US/docs/Web/API/DataTransferItem/kind):
13
+
Fundamentally, the drag data store is a list of items, represented as a {{domxref("DataTransferItemList")}} of {{domxref("DataTransferItem")}} objects. Each item can be one of two [kinds](/en-US/docs/Web/API/DataTransferItem/kind):
14
14
15
15
-`string`: its payload is a string, retrievable with {{domxref("DataTransferItem.getAsString", "getAsString()")}}.
16
16
-`file`: its payload is a file object, retrievable with {{domxref("DataTransferItem.getAsFile", "getAsFile()")}} (or {{domxref("DataTransferItem.getAsFileSystemHandle", "getAsFileSystemHandle()")}} or {{domxref("DataTransferItem.webkitGetAsEntry", "webkitGetAsEntry()")}}, if more complex file system operations are needed).
17
17
18
-
Furthermore the item is also identified by a [type](/en-US/docs/Web/API/DataTransferItem/type), which by convention is in the form of a [MIME type](/en-US/docs/Web/HTTP/Guides/MIME_types). This type can instruct the consumer about how the payload should be parsed or decoded. The list can only have one item of each type, so the list, in effect, is a {{jsxref("Map")}} from type strings to payloads.
18
+
Furthermore the item is also identified by a [type](/en-US/docs/Web/API/DataTransferItem/type), which by convention is in the form of a [MIME type](/en-US/docs/Web/HTTP/Guides/MIME_types). This type can instruct the consumer about how the payload should be parsed or decoded. For all text items, the list can only have one item of each type, so the list, in effect, contains two disjoint collections: a list of files with potentially duplicate types, and a {{jsxref("Map")}} of text items keyed by their type. Generally, the files list represents multiple files being dragged. The text map _does not_ represent multiple resources being transferred, but the same resource encoded in different ways, so that the receiving end can choose the most appropriate supported interpretation. The text items are intended to be sorted in descending order of preference.
19
19
20
20
This list is accessible via the {{domxref("DataTransfer.items")}} property.
21
21
22
22
The HTML Drag and Drop API went through multiple iterations, resulting in two coexisting ways to manage the data store. Before the `DataTransferItemList` and `DataTransferItem` interfaces, the "old way" used the following properties on `DataTransfer`:
23
23
24
24
- {{domxref("DataTransfer.types", "types")}}: contains the `type` properties of the _text items_ in the list, plus the value `"files"` if there are any _file items_.
25
-
- {{domxref("DataTransfer.setData", "setData()")}}, {{domxref("DataTransfer.getData", "getData()")}}, {{domxref("DataTransfer.clearData", "clearData()")}}: operate on the _text items_ in the list using the "type-to-payload mapping" model.
25
+
- {{domxref("DataTransfer.setData", "setData()")}}, {{domxref("DataTransfer.getData", "getData()")}}, {{domxref("DataTransfer.clearData", "clearData()")}}: provide access to the _text items_ in the list using the "type-to-payload mapping" model.
26
26
- {{domxref("DataTransfer.files", "files")}}: provides access to the _file items_ in the list
27
27
28
28
You may see that the types of the _file items_ are not directly exposed. They are still accessible, but only via the {{domxref("Blob.type", "type")}} property of each {{domxref("File")}} object in the `files` list, so if you can't read the files, then you can't know their types either (see [reading the drag data store](#reading_the_drag_data_store) for when the store is readable). It is now recommended to just use the `items` property because it provides a more flexible and consistent interface.
For both methods, if they are called when the data store is unmodifiable, nothing happens. If an item with the same type already exists, `add()` throws an error while `setData()` overwrites the existing item.
50
+
For both methods, if they are called when the data store is unmodifiable, nothing happens. If a text item with the same type already exists, `add()` throws an error while `setData()` overwrites the existing item.
51
51
52
52
To add file data to the drag data store, the "new way" still uses the {{domxref("DataTransferItemList.add()")}} method. Because the "old way" stores file items in the {{domxref("DataTransfer.files")}} property, which is a read-only {{domxref("FileList")}}, there's no direct equivalent.
53
53
@@ -280,4 +280,3 @@ This allows an arbitrary file to be downloaded when dragged to the file explorer
280
280
281
281
-[HTML Drag and Drop API (Overview)](/en-US/docs/Web/API/HTML_Drag_and_Drop_API)
Copy file name to clipboardExpand all lines: files/en-us/web/api/html_drag_and_drop_api/drag_operations/index.md
+42-35Lines changed: 42 additions & 35 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -8,6 +8,14 @@ page-type: guide
8
8
9
9
Central to the Drag and Drop API are the various [drag events](/en-US/docs/Web/API/HTML_Drag_and_Drop_API#drag_events) that fire in a specific order and are expected to be handled in a specific way. This document describes the steps that occur during a drag and drop operation, and what the application is supposed to do within each handler.
10
10
11
+
At a high level, here are the possible steps in a drag and drop operation:
12
+
13
+
- The user [initiates the drag](#starting_a_drag) on a source node; the {{domxref("HTMLElement/dragstart_event", "dragstart")}} event is fired on the source node. Within this event, the source node prepares the context for the drag operation, including the drag data, feedback image, and allowed drop effects.
14
+
- The user [drags the item around](#dragging_over_elements_and_specifying_drop_targets): every time a new element is entered, the {{domxref("HTMLElement/dragenter_event", "dragenter")}} event is fired on that element, and the {{domxref("HTMLElement/dragleave_event", "dragleave")}} event is fired on the previous element. Every few hundred milliseconds, a {{domxref("HTMLElement/dragover_event", "dragover")}} event is fired on the element the drag is currently inside, and the {{domxref("HTMLElement/drag_event", "drag")}} event is fired on the source node.
15
+
- The drag enters a valid drop target: the drop target cancels its `dragover` event to indicate that it is a valid drop target. Some form of [drop feedback](#drop_feedback) indicates the expected drop effect to the user.
16
+
- The user [performs the drop](#performing_a_drop): the {{domxref("HTMLElement/drop_event", "drop")}} event is fired on the drop target. Within this event, the target node reads the drag data.
17
+
- The [drag operation ends](#finishing_the_drag): the {{domxref("HTMLElement/dragend_event", "dragend")}} event is fired on the source node. This event is fired regardless of whether the drop was successful or not.
18
+
11
19
## Starting a drag
12
20
13
21
The drag starts on a [draggable item](/en-US/docs/Web/API/HTML_Drag_and_Drop_API#draggable_items), which can be a selection, a draggable element (including links, images, and any element with `draggable="true"`), a file from the operating system's file explorer, etc. First, the {{domxref("HTMLElement/dragstart_event", "dragstart")}} event is fired on the _source node_, which is the draggable element or, for selections, the text node that the drag started on. If this event is cancelled, then the drag operation is aborted. Otherwise, the {{domxref("HTMLElement/pointercancel_event", "pointercancel")}} event is also fired on the source node.
When a drag occurs, a translucent image is generated from the source node, and follows the user's pointer during the drag. This image is created automatically, so you do not need to create it yourself. However, you can use {{domxref("DataTransfer.setDragImage","setDragImage()")}} to specify a custom drag feedback image.
Three arguments are necessary. The first is a reference to an image. This reference will typically be to an `<img>` element, but it can also be to a `<canvas>` or any other element. The feedback image will be generated from whatever the image looks like on screen, although for images, they will be drawn at their original size. The second and third arguments to the {{domxref("DataTransfer.setDragImage","setDragImage()")}} method are offsets where the image should appear relative to the mouse pointer.
49
59
50
60
It is also possible to use images and canvases that are not in a document. This technique is useful when drawing custom drag images using the canvas element, as in the following example:
@@ -62,20 +72,40 @@ function dragWithCustomImage(event) {
62
72
ctx.lineTo(50, 0);
63
73
ctx.stroke();
64
74
65
-
constdt=event.dataTransfer;
66
-
dt.setData("text/plain", "Data to Drag");
67
-
dt.setDragImage(canvas, 25, 25);
68
-
}
75
+
event.dataTransfer.setDragImage(canvas, 25, 25);
76
+
});
69
77
```
70
78
71
79
In this example, we make one canvas the drag image. As the canvas is 50×50 pixels, we use offsets of half of this (`25`) so that the image appears centered on the mouse pointer.
72
80
73
81
## Dragging over elements and specifying drop targets
74
82
75
-
For the entire course of the drag operation, all device input events (such as mouse or keyboard) are suppressed. Every few hundred milliseconds, a {{domxref("HTMLElement/drag_event", "drag")}} event is fired at the source node.
83
+
For the entire course of the drag operation, all device input events (such as mouse or keyboard) are suppressed. The dragged data can be moved over various elements in the document, or even elements in other documents. Whenever a new element is entered, a {{domxref("HTMLElement/dragenter_event", "dragenter")}} event is fired on that element, and a {{domxref("HTMLElement/dragleave_event", "dragleave")}} event is fired on the previous element.
84
+
85
+
> [!NOTE]
86
+
> `dragleave` always fires _after_`dragenter`, so conceptually, in between these two events, the target has entered a new element but has not exited the previous one yet.
87
+
88
+
Every few hundred milliseconds, two events fire: a {{domxref("HTMLElement/drag_event", "drag")}} event at the source node, and a {{domxref("HTMLElement/dragover_event", "dragover")}} event at the element the drag is currently inside. Most areas of a web page or application are not valid places to drop data, so elements by default ignore any drop that happened on it. The element can elect itself to be a valid drop target by cancelling the `dragover` event. If the element is an editable text field, such as a {{HTMLElement("textarea")}} or [`<input type="text">`](/en-US/docs/Web/HTML/Reference/Elements/input/text), and the data store contains one `text/plain` item, then the element is a valid drop target by default without cancelling `dragover`.
89
+
90
+
```html
91
+
<divid="drop-target">You can drag and then drop a draggable item here</div>
> The spec requires that if you cancel this `drag` event, the drag operation is considered [aborted](#a_failed_drop); in practice no browser implements this. See example below:
103
+
> The spec requires the `dragenter` event to be cancelled too for a drop target, otherwise the `dragover` or `dragleave` events won't even start firing on this element; in practice no browser implements this, and the "current element" changes every time a new element is entered.
104
+
105
+
> [!NOTE]
106
+
> The spec requires that cancelling the `drag` event [aborts](#a_failed_drop) the drag; in practice no browser implements this. See example below:
107
+
>
108
+
> {{EmbedLiveSample("cancel_drag", "", 100)}}
79
109
80
110
```html hidden live-sample___cancel_drag
81
111
<pdraggable="true"id="draggable">Drag me for 1 second!</p>
In the course of the drag operation, the dragged data can be moved over various elements in the document, or even elements in other documents. Whenever a new element is entered, a {{domxref("HTMLElement/dragenter_event", "dragenter")}} event is fired on that element, and a {{domxref("HTMLElement/dragleave_event", "dragleave")}} event is fired on the previous element.
106
-
107
-
> [!NOTE]
108
-
> `dragleave` always fires _after_`dragenter`, so conceptually, in between these two events, the target has entered a new element but has not exited the previous one yet.
109
-
110
-
Every few hundred milliseconds, a {{domxref("HTMLElement/dragover_event", "dragover")}} event is fired on the element the drag is currently inside. Most areas of a web page or application are not valid places to drop data, so elements by default ignore any drop that happened on it. The element can elect itself to be a valid drop target by cancelling the `dragover` event. If the element is an editable text field, such as a {{HTMLElement("textarea")}} or [`<input type="text">`](/en-US/docs/Web/HTML/Reference/Elements/input/text), and the data store contains one `text/plain` item, then the element is a valid drop target by default without cancelling `dragover`.
111
-
112
-
```html
113
-
<divid="drop-target">You can drag and then drop a draggable item here</div>
> The spec requires the `dragenter` event to be cancelled too, otherwise the `dragover` or `dragleave` events won't even start firing on this element; in practice no browser implements this, and the "current element" changes every time a new element is entered.
126
-
127
-
However, you will commonly wish to call the {{domxref("Event.preventDefault","preventDefault()")}} method only in certain situations (for example, only if a link is being dragged). To do this, check a condition and only cancels the event when the condition is met. For example, you can check if the dragged data contains links:
133
+
However, you usually only want the drop target to accept drops in certain situations (for example, only if a link is being dragged). To do this, check a condition and only cancel the event when the condition is met. For example, you can check if the dragged data contains links:
@@ -173,7 +179,7 @@ Note that setting `dropEffect` only indicates the desired effect _at this partic
173
179
For both user gestures and programmatically setting `dropEffect`, by default, all three drop effects are available. The draggable element can restrict itself to only allow certain effects by setting the {{domxref("DataTransfer.effectAllowed","effectAllowed")}} property within a {{domxref("HTMLElement/dragstart_event", "dragstart")}} event listener.
for more information about how to read, see [Working with the drag data store](/en-US/docs/Web/API/HTML_Drag_and_Drop_API/Drag_data_store#reading_the_drag_data_store).
341
347
348
+
It is also the source and the target elements' responsibility to collaborate to implement the `dropEffect`—the source listens for the `dragend` event and the target listens for the `drop` event. For example, if the `dropEffect` is `move`, then one of these elements must remove the dragged item from its old location (usually the source element itself, because the target element doesn't necessarily know or have control over the source).
349
+
342
350
## A failed drop
343
351
344
352
The drag-and-drop operation is considered failed if one of the following is true:
@@ -366,4 +374,3 @@ After the {{domxref("HTMLElement/dragend_event", "dragend")}} event has finished
366
374
367
375
-[HTML Drag and Drop API (Overview)](/en-US/docs/Web/API/HTML_Drag_and_Drop_API)
368
376
-[Working with the drag data store](/en-US/docs/Web/API/HTML_Drag_and_Drop_API/Drag_data_store)
369
-
-[HTML Living Standard: Drag and Drop](https://html.spec.whatwg.org/multipage/interaction.html#dnd)
0 commit comments