Created
April 16, 2017 19:54
-
-
Save Ntropish/3e74c692248ad8ba21b69d8573630aa6 to your computer and use it in GitHub Desktop.
A drag directive for Vue
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
import handle from './handle' | |
document.handlers = handle(document) | |
export default { | |
bind(el, binding, {context: {_uid: id}}) { | |
el.handlers = handle(el) | |
el.handlers.mousedown = downHandler | |
// Namespaced handler | |
document.handlers[id].mouseup = upHandler | |
function downHandler(e) { | |
document.handlers[id].mousemove = moveHandler | |
// Kill default drag and drop | |
e.preventDefault() | |
} | |
function moveHandler(e) { | |
el.dispatchEvent(new CustomEvent('drag', {detail: e})) | |
} | |
function upHandler(e) { | |
document.handlers[id].mousemove = null | |
e.target.dispatchEvent(new CustomEvent('drop', {detail: binding.value})) | |
} | |
}, | |
unbind(el, binding, {context: {_uid: id}}) { | |
el.handlers.clear() | |
document.handlers[id].clear() | |
} | |
} |
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
export default function handle(element) { | |
let root = new Proxy(element, ProxyHandler()) | |
return root | |
function ProxyHandler(namespace = []) { | |
let $handlers = {} | |
let $namespaces = {} | |
return { | |
get(el, prop) { | |
let space = namespace.reduce((p,c)=>p[c], root) | |
// Provide a function to remove all event handlers | |
if (prop === 'clear') { | |
return function clearNamespace(handlers = Object.keys($handlers)) { | |
if (typeof handlers === 'string') handlers = [handlers] | |
Object.keys($namespaces).forEach(namespace=>{ | |
$namespaces[namespace].clear(handlers) | |
}) | |
handlers.forEach(name=>{ | |
let handler = $handlers[name] | |
el.removeEventListener(name, handler) | |
}) | |
} | |
} | |
if (prop === '$handlers') { | |
return $handlers | |
} | |
// Return the Proxy in the desired namespace and make it if needed | |
if (!$namespaces[prop]) { | |
$namespaces[prop] = new Proxy(el, ProxyHandler(namespace.concat(prop))) | |
} | |
return $namespaces[prop] | |
}, | |
set(el, prop, value) { | |
let space = namespace.reduce((p,c)=>p[c], root) | |
// Clear handler if setting to falsy | |
if (!prop) { | |
el.removeEventListener(prop, space.$handlers[prop]) | |
delete space.$handlers[prop] | |
return true | |
} | |
// Only one handler of each event type per namespace | |
if (space.$handlers[prop]) { | |
el.removeEventListener(prop, space.$handlers[prop]) | |
} | |
el.addEventListener(prop, value) | |
space.$handlers[prop] = value | |
return true | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment