LEARNING OBJECTIVES โต
- Understand the architectural relationship and handshake contract between
effectAllowedanddropEffect. - Configure
effectAllowedon the Drag Source duringdragstart. - Negotiate and set
dropEffecton the Drop Target duringdragover. - Identify the operating system cursor glyphs associated with
copy,move,link, andnone. - Implement dynamic modifier key detection (e.g.,
Ctrlfor Copy,Shiftfor Move).
๐ The Mental Model & Story (Intuitive Foundation)
Imagine an international trade negotiation between an Exporter (Drag Source) and an Importer (Drop Target).
- The Exporterโs Manifesto (
effectAllowed): When shipping cargo from the factory, the exporter stamps an export license:- "This container can be Sold (Copy), Relocated (Move), or Leased (Link)" (
effectAllowed = "all"). - Alternatively, for a unique original painting: "This can ONLY be Relocated (Move); copies are strictly forbidden!" (
effectAllowed = "move").
- "This container can be Sold (Copy), Relocated (Move), or Leased (Link)" (
- The Importerโs Customs Station (
dropEffect): When the cargo arrives at the destination port, the customs officer checks their local regulations:- "We are a photocopy archive; we only accept Copies" (
dropEffect = "copy"). - If the exporter's license allows
copy, the transaction is approved! The OS cursor changes to a green plus badge[+]. - If the exporter stated
effectAllowed = "move"(no copies allowed), but the customs officer demandsdropEffect = "copy", the handshake fails. The cursor immediately displays a red crossed-out circle[๐ซ](no-drop), and the drop cannot proceed.
- "We are a photocopy archive; we only accept Copies" (
+---------------------------+ +---------------------------+
| DRAG SOURCE ELEMENT | | DROP TARGET ELEMENT |
| (dragstart) | | (dragover) |
| | | |
| effectAllowed: | ===== Handshake ===> | dropEffect: |
| - 'copy' | Contract | - 'copy' |
| - 'move' | | - 'move' |
| - 'link' | | - 'link' |
| - 'all' | | - 'none' |
+---------------------------+ +---------------------------+
|
v
+-----------------------------------------------------+
| BROWSER OS CURSOR OUTPUT |
| - 'copy': Cursor with [+] badge |
| - 'move': Standard pointer / Drag icon |
| - 'link': Cursor with curved shortcut arrow [โ] |
| - 'none': Crossed circle / Prohibited icon [๐ซ] |
+-----------------------------------------------------+
Technical Deep Dive & Specifications
The Permitted Values Matrix
The browser enforces a strict mathematical compatibility matrix between the source's effectAllowed and the target's dropEffect.
effectAllowed Values (Set in dragstart)
Must be configured when initiating the drag. Setting it in subsequent events has no effect.
| Value | Allowed Operations at Target |
|---|---|
'none' |
The item may not be dropped anywhere. |
'copy' |
Only 'copy' drop effect is permitted. |
'move' |
Only 'move' drop effect is permitted. |
'link' |
Only 'link' drop effect is permitted. |
'copyMove' |
Either 'copy' or 'move' is permitted. |
'copyLink' |
Either 'copy' or 'link' is permitted. |
'linkMove' |
Either 'link' or 'move' is permitted. |
'all' |
Any operation (copy, move, link) is permitted. |
'uninitialized' (default) |
Treated identically to 'all'. |
dropEffect Values (Set in dragover)
Configured on the target to tell the browser which single operation will be performed if the drop occurs here.
| Value | OS Cursor Visual Feedback | Meaning |
|---|---|---|
'copy' |
Pointer with a + badge |
A copy of the source item will be created at the target. |
'move' |
Standard drag arrow / hand | The source item will be removed from old location and placed here. |
'link' |
Pointer with an alias arrow (โ) | A shortcut or reference link to the source item will be created. |
'none' |
Forbidden sign (๐ซ / Circle-slash) | The drop is not allowed here; dropping triggers cancellation. |
Compatibility & Handshake Rules
If a drop target sets dropEffect = 'copy', but the source declared effectAllowed = 'move', the browser detects an incompatible contract. The dropEffect is automatically reset to 'none', rendering the forbidden cursor.
+---------------------------------------+
| Target sets: dropEffect = 'copy' |
+---------------------------------------+
|
Is 'copy' permitted by effectAllowed?
/ \
YES NO
/ \
[ Show (+) Copy Cursor ] [ Override to 'none' (๐ซ) ]
[!IMPORTANT]
dropEffectis purely an instruction to the browser's UI engine to render the correct operating system cursor. SettingdropEffect = 'copy'does not clone DOM nodes automatically! You must write the JavaScript logic inside thedropevent to handle cloning vs. moving.
๐ป Interactive Code Playground
Starter Code
Line-by-Line Code Breakdown
- Line 77 (
e.dataTransfer.effectAllowed = 'all'): Authorizes any destination zone to perform eithercopy,move, orlink. - Line 86 (
e.dataTransfer.dropEffect = effect): In thedragoverhandler, the target assigns its desired effect ('copy','move', or'link'). The browser updates the OS mouse pointer instantaneously. - Line 99โ112 (
if (effect === 'copy') ... else if (effect === 'move')): Demonstrates that the developer must implement the actual business logic for copying vs. moving. The browser only updates the cursor.
Expected Browser Render Output
Hovering over Zone 1 renders a + badge next to the pointer. Over Zone 2, standard move cursor. Over Zone 3, alias link arrow.
+------------------+ +------------------+ +------------------+ +------------------+
| Source Repo | | 1. Duplicate | | 2. Archive | | 3. Shortcut |
| [๐ Financial] | | (Cursor: [+]) | | (Cursor: Move) | | (Cursor: [โ]) |
+------------------+ +------------------+ +------------------+ +------------------+๐๏ธ Hands-On Exercise
๐ฏ The Challenge: Dynamic Modifier Key Router
Instructions:
- Create a draggable file element
"Dataset_2026.csv". - Configure
effectAllowed = 'copyMove'ondragstart. - Create a single drop container
"Central Storage Depot". - In the container's
dragoverlistener, inspectevent.ctrlKey(orevent.altKey):- If the user is holding
Ctrl, setdropEffect = 'copy'(showing+cursor). - If no modifier key is held, set
dropEffect = 'move'(showing Move cursor).
- If the user is holding
- In the
drophandler:- If dropped as
copy, append a"Copied Dataset"entry without removing the source. - If dropped as
move, append a"Moved Dataset"entry and remove the original source.
- If dropped as
๐ Starter Code Sandbox
โ ๏ธ Common Pitfalls
- Configuring
effectAllowedindragover:effectAllowedcan only be modified duringdragstart. Setting it in any subsequent event (drag,dragover,drop) is silently ignored by the browser. - Assuming
dropEffectPerforms Automatic Clones: Developers often believe settingdropEffect = 'copy'automatically duplicates elements. It only updates the OS cursor glyph; you must explicitly executeelement.cloneNode(true)or state updates in JavaScript. - Requesting an Disallowed Effect: If
effectAllowed = 'move', anddropEffect = 'copy', the browser invalidates the operation, resetsdropEffectto'none', and presents a๐ซcursor.
๐ก Pro Tips
- Mac vs. Windows Keyboard Modifiers: On Windows/Linux, the
Ctrlkey traditionally signifies Copy. On macOS, theOption(Alt) key signifies Copy, andCmd(Meta) +Optionsignifies Link. Support both by checkinge.ctrlKey || e.altKey. - Defensive Validation on Drop: Never trust
e.dataTransfer.dropEffectalone on drop; always re-verify your application permissions and state model before committing destructive operations (like deleting the source card).
๐ Key Takeaways
effectAllowedis set on the Drag Source duringdragstartto declare authorized operations.dropEffectis set on the Drop Target duringdragoverto request a specific action from the browser.- The four primary effect types are:
copy(+),move(standard pointer),link(โ), andnone(๐ซ). - If
dropEffectcontradictseffectAllowed, the drop is canceled and the browser displays the forbidden cursor. - Inspecting modifier keys (
event.ctrlKey,event.altKey) duringdragoverprovides desktop-grade user ergonomics. - --