Last active
May 26, 2025 15:41
-
-
Save mauskin/1eef265eb80282a9cf0eb84362fc6937 to your computer and use it in GitHub Desktop.
Minimal cross-browser drag with no drop function
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// The most bare cross-browser drag with no drop function I could do. | |
// Example: | |
// | |
// make_draggable( | |
// thing, | |
// () => console.log("let’s go"), | |
// (event) => { | |
// console.log(event.clientX, event.clientY); | |
// element.style.transform = `translate(${event.clientX}px, ${event.clientY}px)`; | |
// }, | |
// () => console.log("landed") | |
// ); | |
export default Object.freeze(function make_draggable( | |
element, // element, being dragged | |
on_drag_start, // callback, runs once, gets `event` and `drag_state` | |
on_drag, // callback, runs a lot, gets `event` and `drag_state` | |
on_drag_end // callback, runs once, gets `event` and `drag_state` | |
) { | |
if (element === null || element === undefined) { | |
console.error("Element is missing"); | |
return undefined; | |
} | |
if ( | |
typeof on_drag_start !== "function" || | |
typeof on_drag !== "function" || | |
typeof on_drag_end !== "function" | |
) { | |
console.error("All three handlers are required"); | |
return undefined; | |
} | |
let drag_state; | |
function drag_start_handler(event) { | |
element.setPointerCapture(event.pointerId); | |
window.addEventListener("pointermove", drag_handler, true); | |
element.addEventListener("pointerup", drag_end_handler, true); | |
element.addEventListener("pointercancel", drag_end_handler, true); | |
drag_state = Object.create(null); | |
on_drag_start(event, drag_state); | |
} | |
function drag_handler(event) { | |
on_drag(event, drag_state); | |
} | |
function drag_end_handler(event) { | |
window.removeEventListener("pointermove", drag_handler, true); | |
element.removeEventListener("pointerup", drag_end_handler, true); | |
element.removeEventListener("pointercancel", drag_end_handler, true); | |
element.releasePointerCapture(event.pointerId); | |
on_drag_end(event, drag_state); | |
} | |
element.addEventListener("pointerdown", drag_start_handler, true); | |
return Object.freeze(function clean_up() { | |
element.removeEventListener("pointerdown", drag_start_handler, true); | |
window.removeEventListener("pointermove", drag_handler, true); | |
element.removeEventListener("pointerup", drag_end_handler, true); | |
element.removeEventListener("pointercancel", drag_end_handler, true); | |
}); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment