HTML ondragstart Attribute

Beginner
⏱️ 5 min read
📚 Updated: Jun 2026
🎯 3 Examples
Events & Handlers

Introduction

The ondragstart attribute is an inline event handler that runs JavaScript when the dragstart event fires on the draggable source — the element being dragged. It fires once when the user begins dragging. It is part of the HTML Drag and Drop API: set draggable="true" on the source, then use ondragstart to call event.dataTransfer.setData(type, value) so drop targets can read the payload with getData. You can also set event.dataTransfer.effectAllowed and setDragImage for a custom drag ghost. The drag sequence on the source is dragstartdrag (many times) → dragend; drop targets receive dragenter, dragover, and drop. For production sites, prefer addEventListener("dragstart", …) over inline handlers.

What You’ll Learn

01

Event handler

Inline JS.

02

dragstart event

On source.

03

setData

Transfer payload.

04

effectAllowed

Permitted ops.

05

addEventListener

Preferred way.

06

Compare events

drag/dragend/drop.

Purpose of ondragstart Attribute

The primary purpose of ondragstart is to define what happens when a user begins dragging an element. Common uses include calling event.dataTransfer.setData() to attach a payload, setting event.dataTransfer.effectAllowed to declare copy or move intent, and updating a status label to confirm the drag has started. It connects the first moment of a drag gesture to JavaScript without a full page reload.

Do not confuse ondragstart with ondragover—that fires on the drop target while hovering. dragstart fires on the source exactly once. Unlike ondrag (repeated while moving) or ondragend (once when released), dragstart is where you must call setData for drop targets to receive data via getData. Avoid alert() in handlers; update visible status text instead.

💡
draggable="true" is required

Without draggable="true" on the source element, the browser will not fire dragstart and ondragstart never runs. Only certain elements (like links and images) are draggable by default.

📝 Syntax

Set ondragstart on a draggable source or assign element.ondragstart:

ondragstart.html
<script>

  function handleDragStart(event) {

    event.dataTransfer.setData("text/plain", "Hello from dragstart");

    event.dataTransfer.effectAllowed = "move";

    document.getElementById("status").textContent = "dragstart — setData called.";

  }

</script>



<div draggable="true" ondragstart="handleDragStart(event)">Drag me</div>

<p id="status"></p>

Syntax Rules

  • Value is JavaScript code executed once when the user begins dragging the element.
  • dragstart fires on the draggable source, not on drop targets.
  • Set draggable="true" on the source element.
  • Call event.dataTransfer.setData(type, value) so drop targets can read the payload.
  • Optional: set event.dataTransfer.effectAllowed to copy, move, link, or combinations.
  • Optional: call event.dataTransfer.setDragImage(element, x, y) for a custom drag ghost.
  • JavaScript: element.ondragstart = function(event) { … }.
  • Modern alternative: element.addEventListener("dragstart", handler).

💎 Values

The ondragstart attribute accepts a string of JavaScript code:

  • ondragstart="handleDragStart(event)" — Call a named function with the event object.
  • ondragstart="event.dataTransfer.setData('text/plain', 'data')" — Minimal inline setData.
  • JavaScript: source.ondragstart = (e) => { e.dataTransfer.setData(…); … } assigns the handler.
  • Set event.dataTransfer.effectAllowed inside the handler to declare permitted operations.
ondragstart-js.html
const source = document.getElementById("dragSource");



source.addEventListener("dragstart", (event) => {

  event.dataTransfer.setData("text/plain", "Item payload");

  event.dataTransfer.effectAllowed = "move";

  document.getElementById("status").textContent =

    "dragstart — setData enables drop target getData.";

});



document.getElementById("dragSource").ondragstart = function (event) {

  event.dataTransfer.setData("text/plain", "Hello");

  console.log("effectAllowed:", event.dataTransfer.effectAllowed);

};

⚡ Quick Reference

EventWhen it firesHandler
dragstartOnce when drag beginsondragstart
dragRepeatedly while moving sourceondrag
dragendOnce when drag ends (source)ondragend
dropOnce when released on targetondrop
setDataRequired in dragstart for getData on dropevent.dataTransfer.setData(type, value)
effectAllowedSet during dragstart on sourcecopy, move, link, copyMove
draggableRequired on sourcedraggable="true"

Applicable Elements

TargetSupported?Notes
<div>, <span>YesNeeds draggable="true"; common drag sources
<li>YesSortable list items; setData with item id in dragstart
<img>, <a>YesDraggable by default in most browsers
<button>YesNeeds draggable="true"; add keyboard alternative
Drop targetSeparateUse ondragover/ondrop on receivers, not dragstart

ondragstart vs ondrag vs ondragend vs ondrop

HandlerWhen it firesElementTypical use
ondragstartOnce at drag startDraggable sourcesetData, effectAllowed, setDragImage
ondragRepeatedly while movingDraggable sourceLive feedback, opacity, counters during drag
ondragendOnce when drag endsDraggable sourceReset styles, finalize source state
ondropOnce when released on valid targetDrop targetgetData, move DOM node, accept payload

Examples Gallery

Inline ondragstart with setData and status text, dynamic element.ondragstart assignment, and a full mini workflow where dragstart sets data and the drop zone reads it on drop.

👀 Live Preview

Start dragging the box. dragstart calls setData and updates status:

Drag this box.

Waiting for dragstart…

Example — Inline ondragstart on draggable source

Call setData in ondragstart so drop targets can read the payload:

inline-ondragstart.html
<div draggable="true" ondragstart="handleDragStart(event)">Drag me</div>

<p id="msg"></p>



<script>

  function handleDragStart(event) {

    event.dataTransfer.setData("text/plain", "Hello from dragstart");

    event.dataTransfer.effectAllowed = "move";

    document.getElementById("msg").textContent = "dragstart — setData called.";

  }

</script>
Try It Yourself

How It Works

The browser fires dragstart once on the draggable source when the user begins dragging. The inline ondragstart attribute must call event.dataTransfer.setData() so drop targets can retrieve the payload.

Dynamic Values with JavaScript

Assign the handler with element.ondragstart or addEventListener:

dynamic-ondragstart.html
<script>

  document.getElementById("dynamicDraggable").ondragstart = function (event) {

    event.dataTransfer.setData("text/plain", "Dynamic payload");

    event.dataTransfer.effectAllowed = "copyMove";

    document.getElementById("log").textContent =

      "Dynamic dragstart — setData called.";

  };



  // Or preferred form:

  document.getElementById("dynamicDraggable").addEventListener("dragstart", handler);

</script>
Try It Yourself

How It Works

Register the listener once at page load. When the user begins dragging, your handler runs once and sets the transfer data before any drop target can receive it.

Example — dragstart sets data, drop reads it

Full mini workflow: dragstart on the source sets data; the drop zone calls getData on drop:

dragstart-drop-workflow.html
source.addEventListener("dragstart", function (event) {

  event.dataTransfer.setData("text/plain", "Item from dragstart");

  event.dataTransfer.effectAllowed = "move";

});



zone.addEventListener("dragover", function (event) {

  event.preventDefault();

});



zone.addEventListener("drop", function (event) {

  event.preventDefault();

  var payload = event.dataTransfer.getData("text/plain");

  status.textContent = "drop — getData: " + payload;

});
Try It Yourself

How It Works

dragstart initializes the drag operation on the source. Drop targets need preventDefault in dragover to accept the drop, then read the payload set during dragstart.

♿ Accessibility

  • Drag is pointer-heavy — Not all users can drag with a mouse. Provide keyboard or button alternatives for the same action.
  • Announce drag state — Use aria-live regions when dragstart updates status text so screen reader users know a drag has begun.
  • Avoid alert() on dragstart — Inline status text or visible UI updates are more accessible than modal alerts at drag start.
  • Do not rely on drag alone — Finalize important actions in accessible controls, not only after a drag gesture.
  • Visible focus — Ensure draggable elements have sufficient color contrast and do not hide focus outlines.

🧠 How ondragstart Works

1

User begins drag

Pointer moves on element with draggable="true".

draggable
2

dragstart fires once

Call setData, effectAllowed, optional setDragImage on source.

ondragstart
3

drag repeats on source

drag fires many times while pointer moves; dragend fires on release.

ondrag / ondragend
=

Targets receive events

dragenter, dragover, drop on receivers; getData reads payload set in dragstart.

Browser Support

The dragstart event and ondragstart handler are part of the HTML Drag and Drop API and supported in all modern browsers — Chrome, Firefox, Safari, and Edge. Touch drag behavior may differ; test on your target devices.

DOM Events · Fully supported

Universal ondragstart support

All major browsers fire the underlying event and honor the ondragstart handler attribute.

99% Browser support
Google Chrome Fully supported
Full support
Mozilla Firefox Fully supported
Full support
Apple Safari Fully supported
Full support
Microsoft Edge Fully supported
Full support
Internet Explorer IE 9+ supported
Full support
Opera Fully supported
Full support
ondragstart attribute 99% supported

Bottom line: Universal support for dragstart on draggable sources. Always set draggable="true", call setData in dragstart, and pair with drop target handlers.

💡 Best Practices

✅ Do

  • Always setData in dragstart — Required for drop targets to read payload via getData.
  • Use addEventListener on the source — Clearer than inline ondragstart.
  • Set effectAllowed during dragstart — Declare copy, move, or link intent on the source.
  • Keep dragstart lightweight — One-time setup here; use drag for live feedback and dragend for cleanup.
  • Pair with drop target handlers — dragover with preventDefault and drop with getData on receivers.

❌ Don’t

  • Do not use alert() — Update visible status text instead of blocking modal dialogs.

Conclusion

The ondragstart attribute runs JavaScript once when a user begins dragging a draggable source and the dragstart event fires on that element. Its most important job is calling event.dataTransfer.setData() so drop targets can retrieve the payload.

Prefer addEventListener("dragstart", …), set event.dataTransfer.effectAllowed, pair with ondragover/ondrop on receivers, and offer keyboard alternatives for accessibility.

Key Takeaways

Knowledge Unlocked

Five truths every developer should know about ondragstart

Bookmark these before wiring your next event handler.

5
Core concepts
🌐 02

Once at start

Fires one time.

Behavior
🔄 03

setData

Required for getData.

Use case
📝 04

addEventListener

Preferred.

Modern
05

effectAllowed

Declare intent.

Compare

❓ Frequently Asked Questions

It runs JavaScript when the dragstart event fires on a draggable source—once when the user begins dragging that element.
Call event.dataTransfer.setData(type, value) in dragstart to attach a payload. Drop targets read it with getData in the drop handler; without setData the target receives nothing.
ondragstart fires once when dragging begins and is where you set transfer data. ondrag fires continuously on the source while the pointer moves during the drag.
effectAllowed is set on the source during dragstart to declare permitted operations: copy, move, link, or combinations like copyMove.
Prefer element.addEventListener("dragstart", …). Inline ondragstart works for simple demos.
ondragstart fires once on the draggable source when the drag begins. ondrop fires once on the drop target when the user releases the item and is where you read getData.

Start drags with setData

Practice inline ondragstart, addEventListener, effectAllowed, and the full drag-to-drop workflow in the Try It editor.

Try ondragstart demo →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

5 people found this page helpful