This article has participated in the “Digitalstar Project” and won a creative gift package to challenge the creative incentive money.

Drag-and-drop features are common on the Web, such as drag-and-drop sorting, drag-and-drop uploading files, and so on. This article will introduce the DnD(Drag and Drop) API in detail to give you a sense of drag-and-drop functionality.

An overview of the

A typical drag-and-drop operation looks like this: the user selects a draggable element, drags it onto a droppable element, and then releases the mouse.

In this process, the three most important points are:

  • Make elements draggable
  • Allow another element to support placement
  • Data transfer between draggable and placable elements

The sample

Let’s look at a simple example:

Codepen. IO /wuzhengyan2…

<div id="drop-area"></div>
<div id="drag-el" draggable="true">.</div>
Copy the code
window.onload = () = > {
  const dragEl = document.querySelector('#drag-el')
  const dropArea = document.querySelector('#drop-area')

  dragEl.addEventListener('dragstart'.(event) = > {
    event.dataTransfer.setData('text/plain', event.target.id)
  })
  dropArea.addEventListener('dragover'.(event) = > {
    event.preventDefault()
  })
  dropArea.addEventListener('drop'.(event) = > {
    const id = event.dataTransfer.getData('text/plain')
    dropArea.appendChild(document.getElementById(id))
  })
}

Copy the code

The above example is a simple drag-and-drop operation. Let’s look at how the three important points of drag-and-drop are implemented in this example.

  1. Element draggable: Set draggable=true on the DOM property
  2. The element can be placed: listen for the dragover event, which calls preventDefault
  3. Drag and drop data transfer; Dragable elements listen for dragstart events, call the setData method of the dataTransfer object, place elements to listen for drop events, and use the getData method of the dataTransfer object to get the setData.

As you can see, a drag and drop operation is quite simple to implement.

summary

Finally, we conclude from the perspective of draggable elements and placable elements:

For an element to support drag and drop, you need to do three things:

  1. Set the draggable = true
  2. Add dragstart event listener
  3. Set drag and drop data in the listener event

Another element should support placing:

  1. Listen for the dragover event, which calls preventDefault
  2. Listen for the drop event and handle the corresponding logic

By summarizing from the point of view of dragable elements and placable elements, the implementation of drag-and-drop becomes clear. The dragable element defines its drag-and-drop data, and the placable element defines the data to be accepted and the corresponding processing logic, so that the two modules are independent of each other and not coupled to each other.

DnD API

Let’s take a closer look at the DnD apis. Once you’re familiar with these apis, you can perform relatively complex functions.

Draggable attribute

When we want the element to be draggable, we need to set the draggable property.

If the property value is not set, the default value is Auto. In this case, the drag behavior is the default behavior of the browser. Only selected text, links, and images can be dragged.

The draggable property value is not a Boolean type and needs to be explicitly set to true or false, true for dragable and false for undragable

Drag and drop event

The events and trigger times of the drag-and-drop process are as follows:

The event Trigger point
dragstart Triggered when the user starts dragging an element or selected text
drag Triggered when an element or selected text is dragged
dragend Triggered when a drag action ends (such as releasing the mouse button or pressing the “Esc” key)
dragenter Triggered when an element or selected text is dragged to a placable target
dragover Triggered when an element or selected text is dragged to a placeable target (every 100 milliseconds)
drop Emitted when an element or selected text is released on a placable target
dragleave Triggered when a drag element or selected text leaves a placable target.
dragexit Similar to Dragleave, but with poor compatibility, it is recommended not to use it.instructions

Event classification:

  • Dragable elements: dragstart, drag, dragend
  • Placable elements: Dragenter, dragover, drop, dragleave

The event trigger timing can be experienced in this example: codepen. IO /wuzhengyan2…

DragEvent, the event object for drag events, inherits mouseEvent, and dragEvent has a dataTransfer property, which is a dataTransfer object

Here are the common ways of these events:

  • Dragstart: Sets drag data, adjusts drag element styles, etc
  • Drag: Drag movement tracking
  • Dragend: judge whether the drag operation is successful (that is, whether it is released in the drop area, judged by dropEffect), restore the drag element style, etc
  • Dragenter: Sets the style, sets the dropEffect, etc
  • Dragover: Set to steppable area, set dropEffect, etc
  • Drop: Handles the drop event
  • Dragexit: Restores the style

Similarly, let’s look at an example:

Codepen. IO /wuzhengyan2…

<div id="drop-area"></div>
<div id="drag-el" draggable="true">.</div>
<div>Placement results:<span id="result"></span></div>
Copy the code
window.onload = () = > {
  const carEl = document.querySelector('#drag-el')
  const dropArea = document.querySelector('#drop-area')
  const result = document.querySelector('#result')

  carEl.addEventListener('dragstart'.(event) = > {
    event.dataTransfer.setData('text/plain', event.target.id)
    event.dataTransfer.effectAllowed = 'move'
    event.target.style.opacity = 0.5
  })
  carEl.addEventListener('drag'.(event) = > {
    console.log(event.clientX, event.clientY)
  })
  carEl.addEventListener('dragend'.(event) = > {
    event.target.style.opacity = 1
    constisDrop = event.dataTransfer.dropEffect ! = ='none'
    result.innerText = isDrop ? 'success' : 'Not placed'
  })
  dropArea.addEventListener('dragenter'.(event) = > {
    event.dataTransfer.dropEffect = 'move'
    event.target.style.borderStyle = 'dashed'
  })
  dropArea.addEventListener('dragover'.(event) = > {
    event.dataTransfer.dropEffect = 'move'
    event.preventDefault()
  })
  dropArea.addEventListener('drop'.(event) = > {
    const id = event.dataTransfer.getData('text/plain')
    dropArea.appendChild(document.getElementById(id))
    event.target.style.borderStyle = 'solid'
  })
  dropArea.addEventListener('dragleave'.(event) = > {
    event.target.style.borderStyle = 'solid'})}Copy the code

Each event is used in the example above, and each event has its own usage.

Drag and drop data objects

Dragging and dropping data objects involves three classes: DataTransfer, DataTransferItemList, and DataTransferItem

DataTransfer

The DataTransfer object is used to hold data that is dragged during a drag and drop operation, as well as to set drag styles, read drag files, and so on. It can contain one or more data items, each of which contains one or more data types.

All drag events are accessible via event.datatransfer.

Properties:

  • dropEffect: The currently selected drag-and-drop operation type, usually set in the event related to the elements that can be placed
  • effectAllowed: Provides the type of action available, typically set in the event associated with dragging and dropping elements
  • files: contains a list of all local files available for data transfer. If the drag operation does not involve dragging a file, this property is an empty list
  • items: provides a list of all drag dataDataTransferItemListObject, read-only property.
  • types: An array of all data item types

Methods:

  • clearData(): Deletes the data associated with the given type. Type parameters are optional. If the type is empty or unspecified, the data associated with all types is deleted
  • setData(): Sets the data of the given type. If data for that type does not exist, it is added to the end, and the last item in the type list will be the new type. If data of that type already exists, the existing data is replaced in the same place
  • getData(): Gets data of a given type, or returns an empty string if the type does not exist or the dataTransfer does not contain data
  • setDragImage(): Used to set custom drag images.

We’ll look at each property and method in detail.

dropEffecteffectAllowed

DropEffect is used to indicate what drag-and-drop behavior the drop area accepts. It is generally set in dragenter and dragover. The corresponding Effectalhoward indicates what the action of the drag is, which is set in dragStart.

Values supported by Effectalhoward:

  • none: All drag and drop actions are allowed
  • copy: Supports replication
  • move: Supports mobile behavior
  • link: Supports link association behavior
  • copyMove: Supports copy and Move
  • copyLink: Supports copy and link
  • linkMove: Supports Link and Move
  • all: Supports copy, Move, and Link
  • uninitialized: No value is set. By default, the value has the same effect as all

Values supported by dropEffect:

  • none: Cannot be placed
  • copy: Supports replication
  • move: Supports mobile behavior
  • link: Supports link association behavior

These two properties do two things:

  1. The mouse style is displayed based on the Settings. If you look at the previous example, where the move is set, there is a square shape next to the mouse cursor when the element is placed in the drag area
  2. dropEffectThe value of must beeffectAllowedA drop event cannot be triggered by dragging elements in a drop area.

Codepen. IO /wuzhengyan2…

files

This property is defined as an array that corresponds to the entry of the File object if the File is dragged

items

This property holds all drag data and is described below in the DataTransferItemList.

types

This array holds all the data type values of the current drag data. We can look at the default drag values of this array:

Codepen. IO /wuzhengyan2…

You can see that there are three data items to drag when dragging images. They are of type text/uri-list, text/ HTML, and Files.

In addition to these values, you can also use custom grid values, such as Application/X. box mark.

clearData
DataTransfer.clearData([format]);
Copy the code

This method is to clear the drag data item method, no parameters to clear all data, if there is to clear the corresponding type of data.

setData
void dataTransfer.setData(format, data);
Copy the code

Format can use some generic values, such as text/plain, or custom values to set the method for dragging and dropping data. Data is a string, and if your data is an object, you need to serialize it.

By default, data is added to the end of the datatransfer. items array, but if the data type already exists, the value of the previous item is updated.

Data items should be set from the most specific to the least specific. What does that mean? Let’s look at the default data items for link drag.

We can see that the first data item type is text/ urI-lsit, and the corresponding data items are links. The following data items are text and HTML. In terms of links, link addresses are the most specific, and HTML is the least specific.

getData
DOMString dataTransfer.getData(format);
Copy the code

Method of getting drag item data, passing in data type to get.

setDragImage
void dataTransfer.setDragImage(img, xOffset, yOffset);
Copy the code

Drag and drop elements, and the browser will have an image by default. This method allows you to customize drag and drop images.

IO /webgeeker/p…

DataTransferItemList

An array of DataTransferItem, which represents a drag and drop data item. Event.datatransfer. items is of this type

Properties:

  • length: Array length

Methods:

  • add(data, type)Add a drag and drop data item. This method is similar to dataTransfer’s getData, but returns an error when adding data of the same type
  • remove(index)Removes a data item
  • clear()Clear data item

DataTransferItem

Each item in Event.datatransfer. items is of this type

Properties:

  • kind: indicates that the data file or string, the string | file
  • type: Indicates the data type

Methods:

  • getAsFile(callback)Returns File, null if the drag is not a File
  • getAsFileSystemHandle(callback)Returns a file or folder handle, and returns NULL if the drag is not a file
  • getAsString(callback)Return string

Note that DataTransferItem retrieves data asynchronously and dataTransfer getData retrieves data synchronously. Usually we just use the dataTransfer method.

compatibility

The drag and drop API is still mostly used on PCS and is not supported on most mobile devices. The PC is compatible with other browsers except IE.

conclusion

The key points of HTML drag knowledge are the following:

  • How to make elements support drag and drop
  • How do I make elements into placeable areas
  • Drag and drop event
  • Data in drag: dataTransfer object

Master the above knowledge points, can be very good to complete the compilation of drag related functions.

Reference: developer.mozilla.org/en-US/docs/…