Skip to content

Instantly share code, notes, and snippets.

@rolfen
Last active December 4, 2017 09:27
Show Gist options
  • Save rolfen/14720f44e0f4edf74f04 to your computer and use it in GitHub Desktop.
Save rolfen/14720f44e0f4edf74f04 to your computer and use it in GitHub Desktop.
Easy and lean drag-move functionality.
/**
* Minimal drag-move code.
* https://jsfiddle.net/rolfen/68bg5ggw/
*
* @param ele {HTMLElement} the container element to drag
* @param triggers {Array} One or more "drag triggers", areas (inside ele) that will trigger the drag functionality when clicked on.
* @param onDragStart {function} Called when dragging starts (trigger is grabbed)
* @param onDragEnd {function} Called when dragging ends (trigger is released)
*
* Issues:
* - Unsets selection in an attempt to make operation smoother. But there still are selection issues when moving.
* - Bug: triggering page scrolling by trying to move ele beyond the edge of a page is creating some kind of offset.
*
* Usage example (toArray() definition is required):
* ```
* draggable(
* document.querySelector('.palette'),
* toArray(document.querySelectorAll('.palette h2, .palette h3')),
* function() {
* // do something
* }
* );
* ```
*
*/
var draggable = function(ele, triggers, onDragStart, onDragEnd) {
// ele the element that we want to move (the "palette")
// trigger element is assumed to be within ele
triggers.forEach(function(trigger){
trigger.addEventListener("mousedown" , eleMouseDown , false);
});
// offset of click event within ele
var offsetTop = 0;
var offsetLeft = 0;
function clearSelection() {
if(document.selection && document.selection.empty) {
document.selection.empty();
} else if(window.getSelection) {
var sel = window.getSelection();
sel.removeAllRanges();
}
};
function eleMouseDown (ev) {
// register position of click within palette
offsetTop = ev.pageY - ele.offsetTop;
offsetLeft = ev.pageX - ele.offsetLeft;
document.addEventListener ("mousemove" , eleMouseMove , false);
document.addEventListener ("mouseup" , eleMouseUp , false);
if(typeof onDragStart === "function") {
onDragStart();
}
};
function eleMouseMove (ev) {
// offset click to avoid jumping to corner
var pX = ev.pageX - offsetLeft;
var pY = ev.pageY - offsetTop;
// browser window limits
ele.style.left = Math.min(Math.max(pX,0), (window.innerWidth - ele.clientWidth)) + "px";
ele.style.top = Math.min(Math.max(pY,0), (window.innerHeight - ele.clientHeight)) + "px";
// fix selection artefacts. Issue: deletes present selection.
clearSelection();
};
function eleMouseUp () {
document.removeEventListener ("mousemove" , eleMouseMove , false);
document.removeEventListener ("mouseup" , eleMouseUp , false);
if(typeof onDragEnd === "function") {
onDragEnd();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment