Skip to content

Instantly share code, notes, and snippets.

@Ntropish
Created April 16, 2017 19:54
Show Gist options
  • Save Ntropish/3e74c692248ad8ba21b69d8573630aa6 to your computer and use it in GitHub Desktop.
Save Ntropish/3e74c692248ad8ba21b69d8573630aa6 to your computer and use it in GitHub Desktop.
A drag directive for Vue
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()
}
}
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