移动端
export default {
bind: function (el, binding) {
let isDragging = false
let startX,
startY,
deltaX,
deltaY,
x,
y,
isXMove = true,
isYMove = true
// el.style.position="absolute"|"fixed" 元素需要是定位的,也可以在这直接强制加
// 通过使用时携带的修饰符限定只能横向拖动或者纵向拖动
if (binding.modifiers.x) {
// 只有横向移动
isYMove = false
}
if (binding.modifiers.y) {
// 只有纵向移动
isXMove = false
}
el.ontouchstart = (e) => {
isDragging = true
startX = e.touches[0].clientX - el.offsetLeft
startY = e.touches[0].clientY - el.offsetTop
el.ontouchmove = moveHandler
el.ontouchend = upHandler
}
function moveHandler(e) {
e.preventDefault() //阻止默认的处理方式(阻止下拉滑动的效果)
e.stopPropagation()
if (isDragging) {
deltaX = e.touches[0].clientX - startX
deltaY = e.touches[0].clientY - startY
// 处理元素只能在视图内移动,不然移动到屏幕外,元素就消失了,也移动不回来了
deltaX = Math.max(0, deltaX)
deltaY = Math.max(0, deltaY)
deltaX = Math.min(e.view.innerWidth - el.offsetWidth, deltaX)
deltaY = Math.min(e.view.innerHeight - el.offsetHeight, deltaY)
x = deltaX + 'px'
y = deltaY + 'px'
if (isXMove) {
el.style.left = x
}
if (isYMove) {
el.style.top = y
}
}
}
function upHandler(e) {
e.preventDefault() //阻止默认的处理方式(阻止下拉滑动的效果)
e.stopPropagation()
isDragging = false
el.ontouchmove = null
el.ontouchend = null
}
}
}
// 使用
<div v-draggle>添加</div>
<div v-draggle.x>添加</div>
<div v-draggle.y>添加</div>
PC端
export default {
bind: function (el, binding) {
let isDragging = false
let startX,
startY,
deltaX,
deltaY,
x,
y,
isXMove = true,
isYMove = true,
dragDom = el
if (binding.modifiers.x) {
// 只有横向移动
isYMove = false
}
if (binding.modifiers.y) {
// 只有纵向移动
isXMove = false
}
el.onmousedown = (e) => {
isDragging = true
// 如果当前操作当前元素,移动父级元素
if (binding.modifiers.parent) {
dragDom = el.parentNode
}
// 禁止选中文字,防止拖拽时弹框粘鼠标
document.onselectstart = function () {
return false
}
startX = e.x - dragDom.offsetLeft // 鼠标点击在dom上到dom左边的距离
startY = e.y - dragDom.offsetTop // 鼠标点击在dom上到dom上边的距离
el.onmousemove = moveHandler
el.onmouseup = upHandler
}
function moveHandler(e) {
e.preventDefault() //阻止默认的处理方式(阻止下拉滑动的效果)
e.stopPropagation()
if (isDragging) {
deltaX = e.x - startX // 当前鼠标的位置 - 到dom左边的距离 = left
deltaY = e.y - startY // 当前鼠标的位置 - 到dom上边的距离 = top
deltaX = Math.max(0, deltaX) // 不能超出屏幕左边
deltaY = Math.max(0, deltaY) // 不能超出屏幕上边
deltaX = Math.min(window.innerWidth - dragDom.clientWidth, deltaX) // 不能超出屏幕右边 即left < (屏幕宽 - 元素宽)
deltaY = Math.min(window.innerHeight - dragDom.clientHeight, deltaY) // 不能超出屏幕下边 即top < (屏幕高 - 元素高)
x = deltaX + 'px'
y = deltaY + 'px'
if (isXMove) {
dragDom.style.left = x
}
if (isYMove) {
dragDom.style.top = y
}
}
}
function upHandler(e) {
e.preventDefault() //阻止默认的处理方式(阻止下拉滑动的效果)
e.stopPropagation()
isDragging = false
el.onmousemove = null
el.onmouseup = null
}
document.onmouseup = function () {
el.onmousemove = null
el.onmouseup = null
// 在抬起鼠标之后,取消禁用选择文字
document.onselectstart = function () {
return true
}
}
}
}
// 使用
<div v-draggle>添加</div>
<div v-draggle.x>添加</div>
<div v-draggle.y>添加</div>
<div>
<div v-draggle.parent>添加</div>
</div>
注:最后最好还是统一一下,时间不一样,本质上逻辑是一样的