v-drag vue自定义指令-原生js实现拖拽(有碰撞检测)
使用如下
<div v-drag="{id: '.content', fn: dragMethod}" class="about" ></div>
/* eslint-disable */
export default{
inserted: (el, binding) => {
const {id, fn} = binding.value
let scrollTop = document.documentElement.scrollTop || document.body.scrollTop
let scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft
let maxLeft = window.innerWidth + scrollLeft - el.offsetWidth
let maxTop = window.innerHeight + scrollTop - el.offsetHeight
let target = document.querySelector(id)
const context = this
let cloneNode = null
let isflag = false
let prev = 0
let last = 0
el.onmousedown = e => {
// 有滚动条的时候要把滚动距离算在内
//按下鼠标事件
// let ex = e.clientX + scrollLeft - el.offsetLeft
// let ey = e.clientY + scrollTop- el.offsetTop
prev = +new Date()
cloneNode = el.cloneNode(true)
cloneNode.style.position = 'absolute'
cloneNode.style.opacity = 1
cloneNode.style.transition = `opacity 1s linear `
cloneNode.style.cursor = 'move'
cloneNode.style.zIndex = 100
document.onmousemove = e => {
//移动鼠标事件
// let ex1 = e.clientX
// let ey1 = e.clientY
last = +new Date()
if (last - prev > 200) {
document.body.appendChild(cloneNode)
isflag = true
} else {
isflag = false
return
}
let evt = e || window.event
// div跟着走的时候,需要把鼠标按下时的那个相对坐标计算在内
let toLeft = evt.clientX + scrollLeft - el.offsetWidth / 2
let toTop = evt.clientY + scrollTop - el.offsetHeight / 2
// window.innerWidth - div块本身的宽度,就是最大允许left
if (toLeft < 0) {
// 如果left值小于0,则置为0,防止div从左侧被拖出
toLeft = 0
} else if (toLeft > maxLeft) {
// 如果left值大于极限,则置为极限,防止div从右侧被拖出
toLeft = maxLeft
}
// window.innerHeight - div块本身的高度,就是最大允许top
if (toTop < 0) {
// 如果top值小于0,则置为0,防止div从左侧被拖出
toTop = 0
} else if (toTop > maxTop) {
// 如果top值大于极限,则置为极限,防止div从右侧被拖出
toTop = maxTop
}
cloneNode.style.left = toLeft + "px"
cloneNode.style.top = toTop + "px"
}
}
document.onmouseup = function(e) {
if (!cloneNode) {
return
}
let t1 = cloneNode.offsetTop
let l1 = cloneNode.offsetLeft
let r1 = cloneNode.offsetLeft + cloneNode.offsetWidth
let b1 = cloneNode.offsetTop + cloneNode.offsetHeight
let t2,l2,r2,b2
if (target) {
t2 = target.offsetTop
l2 = target.offsetLeft
r2 = target.offsetLeft + target.offsetWidth
b2 = target.offsetTop + target.offsetHeight
}
if(!(b1<t2 || l1>r2 || t1>b2 || r1<l2)){// 表示没碰上
fn.apply(context)
}
if (cloneNode && isflag) {
cloneNode.style.opacity = 0
setTimeout(() => {
document.body.removeChild(cloneNode)
document.onmousemove = null
el.onmouseup = null;
isflag = false
cloneNode = null
}, 200)
}
}
}
}