This text may be dragged.
-``` - -```js -const draggableElement = document.querySelector('p[draggable="true"]'); - -draggableElement.addEventListener("dragstart", (event) => - event.dataTransfer.setData("text/plain", "This text may be dragged"), -); -``` - -The [`draggable`](/en-US/docs/Web/HTML/Reference/Global_attributes/draggable) attribute is set to `"true"`, so this element becomes draggable. If this attribute were omitted or set to `"false"`, the element would not be dragged, and instead the text would be selected. - -The [`draggable`](/en-US/docs/Web/HTML/Reference/Global_attributes/draggable) attribute may be used on any element, including images and links. However, for these last two, the default value is `true`, so you would only use the [`draggable`](/en-US/docs/Web/HTML/Reference/Global_attributes/draggable) attribute with a value of `false` to disable dragging of these elements. - -> [!NOTE] -> When an element is made draggable, text or other elements within it can no longer be selected in the normal way by clicking and dragging with the mouse. Instead, the user must hold down the Alt key to select text with the mouse, or use the keyboard. - -## Starting a drag operation +The `dragstart` event is the only time you can modify the {{domxref("DragEvent.dataTransfer", "dataTransfer")}}. For a custom draggable element, you almost always want to modify the drag data, which is covered in detail in [Modifying the drag data store](/en-US/docs/Web/API/HTML_Drag_and_Drop_API/Drag_data_store#modifying_the_drag_data_store). There are two other things you can change: the [feedback image](#setting_the_drag_feedback_image) and the [allowed drop effects](#drop_effects). In this example, we add a listener for the {{domxref("HTMLElement/dragstart_event", "dragstart")}} event by using the `addEventListener()` method. @@ -53,76 +30,37 @@ In this example, we add a listener for the {{domxref("HTMLElement/dragstart_even ```js const draggableElement = document.querySelector('p[draggable="true"]'); -draggableElement.addEventListener("dragstart", (event) => - event.dataTransfer.setData("text/plain", "This text may be dragged"), -); -``` - -When a user begins to drag, the {{domxref("HTMLElement/dragstart_event", "dragstart")}} event is fired. - -In this example the {{domxref("HTMLElement/dragstart_event", "dragstart")}} listener is added to the draggable element itself. However, you could listen to a higher ancestor as drag events bubble up as most other events do. - -Within the {{domxref("HTMLElement/dragstart_event", "dragstart")}} event, you can specify the **drag data**, the **feedback image**, and the **drag effects**, all of which are described below. However, only the **drag data** is required. (The default image and drag effects are suitable in most situations.) - -## Drag data - -All {{domxref("DragEvent")}} objects have a property called {{domxref("DragEvent.dataTransfer","dataTransfer")}} which holds the drag data (`dataTransfer` is a {{domxref("DataTransfer")}} object). - -When a drag occurs, data must be associated with the drag which identifies _what_ is being dragged. For example, when dragging the selected text within a textbox, the data associated with the _drag data item_ is the text itself. Similarly, when dragging a link on a web page, the drag data item is the link's URL. - -The {{domxref("DataTransfer")}} contains two pieces of information, the **type** (or format) of the data, and the data's **value**. The format is a type string (such as [`text/plain`](/en-US/docs/Web/API/HTML_Drag_and_Drop_API/Recommended_drag_types#dragging_text) for text data), and the value is a string of text. When the drag begins, you add data by providing a type and the data. During the drag, in an event listener for the {{domxref("HTMLElement/dragenter_event", "dragenter")}} and {{domxref("HTMLElement/dragover_event", "dragover")}} events, you use the data types of the data being dragged to check whether a drop is allowed. For instance, a drop target that accepts links would check for the type [`text/uri-list`](/en-US/docs/Web/API/HTML_Drag_and_Drop_API/Recommended_drag_types#dragging_links). During a drop event, a listener would retrieve the data being dragged and insert it at the drop location. - -The {{domxref("DataTransfer")}}'s {{domxref("DataTransfer.types","types")}} property returns a list of MIME-type like strings, such as [`text/plain`](/en-US/docs/Web/API/HTML_Drag_and_Drop_API/Recommended_drag_types#dragging_text) or [`image/jpeg`](/en-US/docs/Web/API/HTML_Drag_and_Drop_API/Recommended_drag_types#dragging_images). You can also create your own types. The most commonly used types are listed in the article [Recommended Drag Types](/en-US/docs/Web/API/HTML_Drag_and_Drop_API/Recommended_drag_types). - -A drag may include data items of several different types. This allows data to be provided in more specific types, often custom types, yet still provide fallback data for drop targets that do not support more specific types. It is usually the case that the least specific type will be normal text data using the type [`text/plain`](/en-US/docs/Web/API/HTML_Drag_and_Drop_API/Recommended_drag_types#dragging_text). - -To set a drag data item within the {{domxref("DragEvent.dataTransfer","dataTransfer")}}, use the {{domxref("DataTransfer.setData","setData()")}} method. It takes two arguments: the type of data and the data value. For example: - -```js -event.dataTransfer.setData("text/plain", "Text to drag"); -``` - -In this case, the data value is "Text to drag" and is of the format [`text/plain`](/en-US/docs/Web/API/HTML_Drag_and_Drop_API/Recommended_drag_types#dragging_text). - -You can provide data in multiple formats. To do this, call the {{domxref("DataTransfer.setData","setData()")}} method multiple times with different formats. You should call it with formats in order from most specific to least specific. - -```js -const dt = event.dataTransfer; -dt.setData("application/x.bookmark", bookmarkString); -dt.setData("text/uri-list", "https://www.mozilla.org"); -dt.setData("text/plain", "https://www.mozilla.org"); +draggableElement.addEventListener("dragstart", (event) => { + event.dataTransfer.setData("text/plain", "This text may be dragged"); +}); ``` -Here, data is added in three different types. The first type, `application/x.bookmark`, is a custom type. Other applications won't support this type, but you can use a custom type for drags between areas of the same site or application. - -By providing data in other types as well, we can also support drags to other applications in less specific forms. The `application/x.bookmark` type can provide data with more details for use within the application whereas the other types can include just a single URL or text version. - -Note that both the [`text/uri-list`](/en-US/docs/Web/API/HTML_Drag_and_Drop_API/Recommended_drag_types#dragging_links) and [`text/plain`](/en-US/docs/Web/API/HTML_Drag_and_Drop_API/Recommended_drag_types#dragging_text) contain the same data in this example. This will often be true, but doesn't need to be the case. - -If you attempt to add data twice with the same format, the new data will replace the old data, but in the same position within the list of types as the old data. - -You can clear the data using the {{domxref("DataTransfer.clearData","clearData()")}} method, which takes one argument: the type of the data to remove. +You could also listen to a higher ancestor as drag events bubble up as most other events do. For this reason, it is common to also check the event's target, so that dragging a selection contained within this element does not trigger the `setData` (although selecting text within the element is hard, it is not impossible): ```js -event.dataTransfer.clearData("text/uri-list"); +draggableElement.addEventListener("dragstart", (event) => { + if (event.target === draggableElement) { + event.dataTransfer.setData("text/plain", "This text may be dragged"); + } +}); ``` -The `type` argument to the {{domxref("DataTransfer.clearData","clearData()")}} method is optional. If the `type` is not specified, the data associated with all types is removed. If the drag contains no drag data items, or all of the items have been subsequently cleared, then no drag will occur. +### Setting the drag feedback image -## Setting the drag feedback image - -When a drag occurs, a translucent image is generated from the drag target (the element the {{domxref("HTMLElement/dragstart_event", "dragstart")}} event is fired at), 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. +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. ```js -event.dataTransfer.setDragImage(image, xOffset, yOffset); +draggableElement.addEventListener("dragstart", (event) => { + event.dataTransfer.setDragImage(image, xOffset, yOffset); +}); ``` Three arguments are necessary. The first is a reference to an image. This reference will typically be to an `