HTML5 Drag and Drop effectAllowed and dropEffect
Categories:
Mastering HTML5 Drag and Drop: effectAllowed and dropEffect

Unlock the full potential of HTML5 Drag and Drop by understanding and effectively using effectAllowed and dropEffect to control drag-and-drop behavior and visual feedback.
HTML5 Drag and Drop provides a powerful native mechanism for users to interact with web content by dragging elements. While the basic implementation is straightforward, achieving precise control over the drag operation's visual feedback and allowed actions requires a deeper understanding of two key properties: effectAllowed and dropEffect. These properties work in tandem to define what kind of drag operation is permitted by the source element and what kind of operation is actually performed by the target element.
Understanding effectAllowed: The Source's Declaration
The effectAllowed property is set on the dataTransfer object during the dragstart event. It declares the types of operations that the drag source is willing to allow. Think of it as the source element's 'permission slip' for the drag operation. The browser uses this value to determine the default cursor feedback shown to the user, indicating what might happen if the element is dropped.
effectAllowed is crucial for providing early visual cues to the user. If effectAllowed is not set, it defaults to uninitialized, which behaves like all in most browsers, potentially leading to less precise feedback.Here are the possible values for effectAllowed:
graph TD
A[effectAllowed Values] --> B{copy}
A --> C{move}
A --> D{link}
A --> E{copyLink}
A --> F{copyMove}
A --> G{linkMove}
A --> H{all}
A --> I{none}
A --> J{uninitialized}Possible values for the effectAllowed property
document.getElementById('draggable').addEventListener('dragstart', function(event) {
event.dataTransfer.effectAllowed = 'copyMove'; // Source allows copying or moving
event.dataTransfer.setData('text/plain', 'This is draggable data');
});
Setting effectAllowed on the drag source
Understanding dropEffect: The Target's Action
The dropEffect property is set on the dataTransfer object during the dragenter or dragover events on a drop target. It declares the actual operation that will occur if the element is dropped on this specific target. The browser uses dropEffect to update the cursor feedback to reflect the action that will be performed by the target. It's important to note that dropEffect must be one of the effects permitted by effectAllowed.
dropEffect set by the target is not one of the operations allowed by the source's effectAllowed, the drop will not be permitted, and the cursor will typically indicate a 'no-drop' state.The possible values for dropEffect are a subset of effectAllowed:
graph TD
A[dropEffect Values] --> B{copy}
A --> C{move}
A --> D{link}
A --> E{none}Possible values for the dropEffect property
document.getElementById('dropzone').addEventListener('dragover', function(event) {
event.preventDefault(); // Allow drop
event.dataTransfer.dropEffect = 'copy'; // Target intends to copy
});
document.getElementById('dropzone').addEventListener('drop', function(event) {
event.preventDefault();
const data = event.dataTransfer.getData('text/plain');
console.log('Dropped data:', data, 'with effect:', event.dataTransfer.dropEffect);
// Perform the 'copy' operation here
});
Setting dropEffect on the drop target and handling the drop
Interaction and Visual Feedback
The browser's cursor feedback is a direct result of the interplay between effectAllowed and dropEffect. When an element is dragged, the browser first looks at the effectAllowed value from the dragstart event. As the dragged element hovers over potential drop targets, the dragover event fires. Inside this event, the target can set its dropEffect. The browser then compares the target's dropEffect with the source's effectAllowed.
If the dropEffect is compatible with effectAllowed (i.e., dropEffect is one of the operations permitted by effectAllowed), the browser displays the cursor corresponding to the dropEffect. If they are incompatible, the browser displays a 'no-drop' cursor. This dynamic feedback is crucial for a good user experience.
sequenceDiagram
participant Source as Draggable Element
participant Browser
participant Target as Drop Zone
Source->>Browser: dragstart (effectAllowed = 'copyMove')
Browser->>Browser: Display 'copy' or 'move' cursor (default based on effectAllowed)
Browser->>Target: dragenter
Target->>Browser: dragover (preventDefault(), dropEffect = 'copy')
Browser->>Browser: Check if 'copy' is allowed by 'copyMove'
Browser->>Browser: Display 'copy' cursor
Browser->>Target: dragover (preventDefault(), dropEffect = 'move')
Browser->>Browser: Check if 'move' is allowed by 'copyMove'
Browser->>Browser: Display 'move' cursor
Browser->>Target: dragover (preventDefault(), dropEffect = 'link')
Browser->>Browser: Check if 'link' is allowed by 'copyMove'
Browser->>Browser: Display 'no-drop' cursor (link not allowed)
Browser->>Target: drop (if allowed)
Target->>Target: Perform action based on event.dataTransfer.dropEffectInteraction between effectAllowed, dropEffect, and browser cursor feedback
event.preventDefault() call within dragover is essential. Without it, the browser will not allow a drop, and the dropEffect you set will have no visual impact.By carefully setting effectAllowed on your draggable elements and dropEffect on your drop targets, you can create intuitive and responsive drag-and-drop interfaces that clearly communicate the intended actions to your users.