在vue中全局引入
// 引入全局的移动的效果
const drag = Vue.directive('drag', {
bind: function (el, binding, vnode) {
let odiv = el; //获取当前元素
el.onmousedown = (e) => {
//算出鼠标相对元素的位置
let disX = e.clientX - odiv.offsetLeft;
let disY = e.clientY - odiv.offsetTop;
let left = '';
let top = '';
document.onmousemove = (e)=>{
//用鼠标的位置减去鼠标相对元素的位置,得到元素的位置
left = e.clientX - disX;
top = e.clientY - disY;
var docWidth = document.body.clientWidth//网页可见宽
var docHeight = document.body.clientHeight//网页可见高
if(top>docHeight-210){//超下边界(键盘DIV长宽分别为 295px、210px)
top = docHeight-210
}
if(top<0){//超上边界
top=0
}
if(left>docWidth-295){//超右边界
left = docWidth-295
}
if(left<0){//超左边界
left=0
}
//绑定元素位置到positionX和positionY上面
//移动当前元素
odiv.style.left = left + 'px';
odiv.style.top = top + 'px';
};
document.onmouseup = (e) => {
document.onmousemove = null;
document.onmouseup = null;
};
};
}
});
Vue.prototype.$drag = drag
推荐使用第二种
// 引入拖拽
Vue.directive('drag', (el) => {
const oDiv = el // 当前元素
const minTop = oDiv.getAttribute('drag-min-top')
const ifMoveSizeArea = 20
oDiv.onmousedown = e => {
let target = oDiv
while (window.getComputedStyle(target).position !== 'absolute' && target !== document.body) {
target = target.parentElement
}
document.onselectstart = () => {
return false
}
if (!target.getAttribute('init_x')) {
target.setAttribute('init_x', target.offsetLeft)
target.setAttribute('init_y', target.offsetTop)
}
const initX = parseInt(target.getAttribute('init_x'))
const initY = parseInt(target.getAttribute('init_y'))
// 鼠标按下,计算当前元素距离可视区的距离
const disX = e.clientX - target.offsetLeft
const disY = e.clientY - target.offsetTop
document.onmousemove = e => {
// 通过事件委托,计算移动的距离
// 因为浏览器里并不能直接取到并且使用clientX、clientY,所以使用事件委托在内部做完赋值
const l = e.clientX - disX
const t = e.clientY - disY
// 计算移动当前元素的位置,并且给该元素样式中的left和top值赋值
target.style.left = l + 'px'
target.style.top = (t < minTop ? minTop : t) + 'px'
if (Math.abs(l - initX) > ifMoveSizeArea || Math.abs(t - initY) > ifMoveSizeArea) {
target.setAttribute('dragged', '')
} else {
target.removeAttribute('dragged')
}
}
document.onmouseup = e => {
document.onmousemove = null
document.onmouseup = null
document.onselectstart = null
}
// return false不加的话可能导致黏连,拖到一个地方时div粘在鼠标上不下来,相当于onmouseup失效
return false
}
})
使用位置 记得移动的时候要绝对定位
<template>
<div>
<div class="some-panel">
<!-- drag-min-top="50" 距离上方的距离 -->
<div v-drag style="height: 20px; background-color: blue"></div>
</div>
</div>
</template>
<script>
export default {
}
</script>
<style scoped>
.some-panel {
width: 200px;
height: 140px;
position: absolute;
left: 20px;
top: 20px;
background-color: coral;
}
/* .some-panel[dragged] {
height: 200px;
} */
</style>
在组件中使用
directives: {
drag: {
// 指令的定义
bind: function (el) {
let odiv = el; //获取当前元素
el.onmousedown = (e) => {
//算出鼠标相对元素的位置
let disX = e.clientX - odiv.offsetLeft;
let disY = e.clientY - odiv.offsetTop;
let left = '';
let top = '';
document.onmousemove = (e)=>{
//用鼠标的位置减去鼠标相对元素的位置,得到元素的位置
left = e.clientX - disX;
top = e.clientY - disY;
var docWidth = document.body.clientWidth//网页可见宽
var docHeight = document.body.clientHeight//网页可见高
if(top>docHeight-210){//超下边界(键盘DIV长宽分别为 295px、210px)
top = docHeight-210
}
if(top<0){//超上边界
top=0
}
if(left>docWidth-295){//超右边界
left = docWidth-295
}
if(left<0){//超左边界
left=0
}
//绑定元素位置到positionX和positionY上面
//移动当前元素
odiv.style.left = left + 'px';
odiv.style.top = top + 'px';
};
document.onmouseup = (e) => {
document.onmousemove = null;
document.onmouseup = null;
};
};
}
}
}
}