Drag and Drop API keynotes
- Published on
- -4 mins read
- Authors
- Name
- Andy Nur (Andy)
- @andynur
I created an example about Javascript Drag-n-Drop APIs at https://hta218.github.io/dnd-keynotes
Below are some interesting key-notes I've learned about the APIs.
Basic concepts
-
A typical drag operation begins when a user selects a draggable element, drags the element to a dropzone, and then releases the dragged element.
-
Events:
Event | Fires when… |
---|---|
drag | …a dragged item (element or text selection) is dragged. |
dragend | …a drag operation ends (such as releasing a mouse button or hitting the Esc key) |
dragenter | …a dragged item enters a valid drop target. |
dragexit | …an element is no longer the drag operation's immediate selection target. |
dragleave | …a dragged item leaves a valid drop target. |
dragover | …a dragged item is being dragged over a valid drop target, every few hundred milliseconds. |
dragstart | …the user starts dragging an item. |
drop | …an item is dropped on a valid drop target. |
Keynotes
-
To make an element draggable, add
draggable="true"
attribute<div draggable="true">This element is draggable</div> -
dragstart
-
dragstart
is the first event fired when a drag operation starts on a draggable element -
use
e.dataTransfer.setData()
method to set any drag's data, this will stay during the drag operation
// The `dragstart` event fires on the `draggable` elementdragElem.addEventListener('dragstart', function (e) {// We can set data using `e.dataTransfer.setData` methode.dataTransfer.setData('text/plain', e.target.id)// Use e.dataTransfer.setDragImage() to change the drag image// e.dataTransfer.setDragImage(img | element, xOffset, yOffset)})- If you don't want the translucent image generated from the drag target during drag, use
e.dataTransfer.setDragImage()
to change it
-
-
The dropEffect
- The dropEffect property is used to control the feedback the user is given during a drag-and-drop operation
dragElem.addEventListener('dragstart', function (e) {e.dataTransfer.setData('text/plain', e.target.id)// The `move` value works on window, not on macOS - It might be the problem of browser along with OSe.dataTransfer.dropEffect = 'move' // or "copy"})-
dropEffect
property could be:move
: dragged data will be moved to the dropzone.copy
: dragged data will be copied to the dropzone.- ..
-
The dropzone
-
To make an element becomes a dropzone, it must have both dragover and drop event handler.
-
Remember to call e.preventDefault() in
dragover
handler or the browser won't let you drop anything inside
dropzone.addEventListener('dragover', function handleDragOver(e) {// The `dropzone` element must have both `dragover` and `drop` event// Remember to preventDefault the behavior or the browser or it will not let you drop anything insidee.preventDefault()e.dataTransfer.dropEffect = 'move'})dropzone.addEventListener('drop', function handleDrop(e) {// NOTE: there must be a handler for dragover to use drop evente.preventDefault()// Use `e.dataTransfer.getData` method to retrieve drag's data and process themconst data = e.dataTransfer.getData('text/plain')// NOTE: Keep mind that we can only use the `dataTransfer.getData()` in the `drop-handler`// `getData()` will return empty string inside handle dragover or dragenter})- Keep mind that we can only use the
dataTransfer.getData()
in thedrop-handler
(it will return empty string inside dragover or dragenter handler)
-
-
dragend
- The dragend event fires after a drag operation finished regardless of whether the drag completed or was canceled
// The `dragend` event fired on the `draggable` element (not the dropzone element)dragElem.addEventListener('dragend', function handleDragEnd(e) {// We can check if the drag was successful or not by checking the ʻe.dataTransfer.dropEffect` valueconst dropEffect = e.dataTransfer.dropEffect// If that fails, the value of `e.dataTransfer.dropEffect` will be "none"})- If the drag operation failed, the value of
e.dataTransfer.dropEffect
will be"none"