Last active
December 4, 2017 09:27
-
-
Save rolfen/14720f44e0f4edf74f04 to your computer and use it in GitHub Desktop.
Easy and lean drag-move functionality.
This file contains 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
/** | |
* 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