👀 Live Preview
Drag the box into the drop zone, then out again. dragleave removes the highlight:
Waiting for dragenter or dragleave…

The ondragleave attribute is an inline event handler that runs JavaScript when the dragleave event fires on a drop target. That happens when a dragged item’s pointer crosses out of the target element’s boundary. It is part of the HTML Drag and Drop API: pair a draggable="true" source with a receiver that listens for dragenter, dragover, dragleave, and drop. Use ondragleave mainly to remove visual feedback (unhighlight the zone) that ondragenter added. To allow a drop, call event.preventDefault() in dragover—not in dragleave. Watch for nested children: moving into a child fires dragleave on the parent—use an enter/leave counter or event.relatedTarget. For production sites, prefer addEventListener("dragleave", …) over inline handlers.
Inline JS.
On drop target.
Pair with dragenter.
True exit check.
Preferred way.
Nested children.
ondragleave AttributeThe primary purpose of ondragleave is to define what happens when a dragged item leaves a drop target. Common uses include removing a highlight class, resetting a status label (“Drop here” → idle), or stopping a subtle animation so users know the zone is no longer active. It connects pointer movement out of a receiver to JavaScript cleanup without a full page reload.
Do not confuse ondragleave with ondragend—that fires on the source when the drag gesture ends. dragleave fires on the target when the pointer exits its boundary. Pair it with ondragenter to add and remove highlights symmetrically. dragover fires repeatedly while hovering and is where preventDefault() enables dropping. When nested children exist, a naive dragleave handler may unhighlight too early—use a counter or check event.relatedTarget. Avoid alert() in handlers; update visible status text instead.
Entering a child inside the drop zone fires dragleave on the parent and dragenter on the child, which can flicker highlights. Increment a counter on dragenter, decrement on dragleave, and remove highlight only when the count reaches 0. Or skip unhighlight when zone.contains(event.relatedTarget).
Set ondragleave on a drop target or assign element.ondragleave:
<script>
function handleDragLeave(event) {
var zone = document.getElementById("dropZone");
if (!zone.contains(event.relatedTarget)) {
zone.classList.remove("over");
document.getElementById("status").textContent = "dragleave — pointer left zone.";
}
}
</script>
<div draggable="true">Drag me</div>
<div id="dropZone" ondragenter="handleDragEnter(event)" ondragleave="handleDragLeave(event)">Drop zone</div>
<p id="status"></p>dragleave fires on the drop target, not on the draggable source.draggable="true" source with handlers on the receiver.event.preventDefault() in dragover on the target to allow drop.dragleave can fire when entering nested children—use a counter or relatedTarget checks.element.ondragleave = function(event) { … }.element.addEventListener("dragleave", handler).The ondragleave attribute accepts a string of JavaScript code:
ondragleave="handleDragLeave(event)" — Call a named function with the event object.ondragleave="this.classList.remove('over')" — Inline statement to unhighlight the target.zone.ondragleave = (e) => { … } assigns the handler.ondragenter or a counter to add highlight when the pointer enters.const zone = document.getElementById("dropZone");
let enterCount = 0;
zone.addEventListener("dragenter", (event) => {
enterCount += 1;
zone.classList.add("over");
document.getElementById("status").textContent =
"dragenter — entered drop zone.";
});
zone.addEventListener("dragleave", (event) => {
enterCount -= 1;
if (enterCount === 0) {
zone.classList.remove("over");
document.getElementById("status").textContent =
"dragleave — left drop zone.";
}
});
zone.addEventListener("dragover", (event) => {
event.preventDefault();
});
document.getElementById("dropZone").ondragleave = function (event) {
console.log("Pointer left target.", event.relatedTarget);
};| Event | When it fires | Handler |
|---|---|---|
dragenter | Pointer enters target boundary | ondragenter |
dragover | Repeatedly while over target | ondragover |
dragleave | Pointer leaves target boundary | ondragleave |
drop | Item released on valid target | ondrop |
preventDefault | Required in dragover to allow drop | Not required in dragleave for cleanup |
relatedTarget | Element being entered on dragleave | Use with contains() for true exits |
| Nested children | dragleave may fire when entering child | Use enter counter pattern |
| Target | Supported? | Notes |
|---|---|---|
<div>, <section> | Yes | Common drop zones; no draggable needed on target |
<ul>, <li> | Yes | Sortable lists; watch nested dragleave events |
<td>, <th> | Yes | Table cell drop targets |
<article>, <main> | Yes | Large layout drop areas |
| Draggable source | Separate | Set draggable="true" on source; use ondragstart there |
ondragleave vs ondragenter vs ondragover vs ondrop| Handler | When it fires | Element | Typical use |
|---|---|---|---|
ondragenter | Boundary entered | Drop target | Highlight zone, show “drop here” status |
ondragover | Repeatedly while hovering | Drop target | preventDefault() to allow drop; continuous feedback |
ondragleave | Boundary left | Drop target | Remove highlight; pair with dragenter |
ondrop | Once when released on valid target | Drop target | Accept payload, move DOM node, update data |
Inline ondragleave removing highlight paired with dragenter, dynamic element.ondragleave assignment, and the enter/leave counter pattern for nested drop zones.
Drag the box into the drop zone, then out again. dragleave removes the highlight:
Waiting for dragenter or dragleave…
Remove highlight when a draggable item leaves the target boundary, paired with ondragenter:
<div draggable="true">Drag me</div>
<div id="dropZone" ondragenter="handleDragEnter(event)" ondragleave="handleDragLeave(event)">Drop zone</div>
<p id="msg"></p>
<script>
function handleDragEnter(event) {
document.getElementById("dropZone").classList.add("over");
document.getElementById("msg").textContent = "dragenter — entered drop zone.";
}
function handleDragLeave(event) {
var zone = document.getElementById("dropZone");
if (!zone.contains(event.relatedTarget)) {
zone.classList.remove("over");
document.getElementById("msg").textContent = "dragleave — left drop zone.";
}
}
</script>The browser fires dragleave on the drop target when the dragged item exits its boundary. The inline ondragleave attribute calls your cleanup function.
Assign the handler with element.ondragleave or addEventListener:
<script>
document.getElementById("dynamicDropTarget").ondragleave = function (event) {
if (!event.currentTarget.contains(event.relatedTarget)) {
event.currentTarget.classList.remove("over");
document.getElementById("log").textContent =
"Dynamic dragleave — pointer left target.";
}
};
// Or preferred form:
document.getElementById("dynamicDropTarget").addEventListener("dragleave", handler);
</script>Register the listener once at page load. When the pointer exits the drop target during a drag, your handler runs on the receiver element.
Increment on dragenter, decrement on dragleave, unhighlight only when count reaches 0:
let enterCount = 0;
zone.addEventListener("dragenter", () => {
enterCount += 1;
zone.classList.add("over");
});
zone.addEventListener("dragleave", () => {
enterCount -= 1;
if (enterCount === 0) zone.classList.remove("over");
});
zone.addEventListener("dragover", (e) => { e.preventDefault(); });Each boundary crossing increments or decrements the counter. Only when enterCount === 0 does the handler remove the highlight—avoiding flicker from nested child elements.
aria-live regions when dragleave clears a highlight so screen reader users know the zone is inactive.dragstart fires on draggable source.
dragenter fires; add highlight on drop target.
dragover fires repeatedly; call preventDefault.
dragleave removes highlight; drop accepts payload.
The dragleave event and ondragleave 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.
ondragleave supportAll major browsers fire the underlying event and honor the ondragleave handler attribute.
Bottom line: Universal support for dragleave on drop targets. Pair with dragenter, dragover + preventDefault(), and a draggable source.
ondragleave.The ondragleave attribute runs JavaScript when a dragged item leaves a drop target and the dragleave event fires on the receiver. Use it to remove highlighting and reset status feedback—paired with ondragenter for symmetric visual states.
Prefer addEventListener("dragleave", …), use an enter/leave counter or event.relatedTarget for nested zones, call preventDefault() in dragover, and offer keyboard alternatives for accessibility.
ondragleaveBookmark these before wiring your next event handler.
dragleave on receiver.
EventPointer crosses out.
BehaviorPair with dragenter.
Use casePreferred.
ModernNested children.
Comparedragleave event fires on a drop target—when a dragged item’s pointer leaves that element’s boundary.event.preventDefault() in dragover on the drop target to allow dropping. dragleave is mainly for removing visual feedback when the pointer exits.ondragenter fires when the pointer crosses into the target boundary and adds highlight. ondragleave fires when the pointer leaves and removes highlight. Use both on the same drop target.dragleave fires on the parent even though the pointer is still inside the zone. Use an enter/leave counter or check event.relatedTarget.element.addEventListener("dragleave", …). Inline ondragleave works for simple demos.event.relatedTarget is the element the pointer is entering when dragleave fires. Use zone.contains(event.relatedTarget) to distinguish a true exit from a move into a nested child.Practice inline ondragleave, addEventListener, relatedTarget checks, and the counter pattern in the Try It editor.
5 people found this page helpful