Gajus
Gajus

Reputation: 73728

How to get mouseup event after native drag event?

The implementation of the WHATWG drag and drop supports dragstart, drag and dragend events.

The dragend event fires when the draggable object returns to the original position, e.g. try dragging the red box as far as you can and release it. The dragend (and "END!" console.log message) will not fire until the draggable element returns to the original position (this is most visible in the Safari browser).

var handle = document.querySelector('#handle');

handle.addEventListener('dragend', function () {
    console.log('END!');
});
#handle {
    background: #f00; width: 100px; height: 100px;
}
<div id="handle" draggable="true"></div>

How do I capture the mouseup or whatever else event that would indicate the release of the drag handle without a delay?

I have tried variations of:

var handle = document.querySelector('#handle');

handle.addEventListener('dragend', function () {
    console.log('END!');
});

handle.addEventListener('mouseup', function () {
    console.log('Mouseup');
});
#handle {
    background: #f00; width: 100px; height: 100px;
}
<div id="handle" draggable="true"></div>

Though, "mouseup" does not fire after dragstart.

The closest I got to finding an event that would fire instantly after the release of the handle is mousemove:

var handle = document.querySelector('#handle');

handle.addEventListener('dragend', function () {
    console.log('END!');
});

window.addEventListener('mousemove', function () {
   console.log('I will not fire during the drag event. I will fire after handle has been released and mouse is moved.'); 
});
#handle {
    background: #f00; width: 100px; height: 100px;
}
<div id="handle" draggable="true"></div>

The problem is that this approach requires user to move the mouse.

Upvotes: 1

Views: 2699

Answers (1)

Gajus
Gajus

Reputation: 73728

The workaround is to enable drop on the document.body:

// @see https://developer.mozilla.org/en-US/docs/Web/Events/dragover
document.body.addEventListener('dragover', function (e) {
    // Prevent default to allow drop.
    e.preventDefault();
});

document.body.addEventListener('drop', function (e) {
    // Prevent open as a link for some elements.
    e.preventDefault();
});

Making document.body to listen for the drop event results in dragend thinking that you will move the element to the new position upon releasing the handle. Therefore, there is no delay between handle release and dragend.

Upvotes: 2

Related Questions