实现方式1:方法直接挂在mounted中
<template>
<div>
<div class="add_card" ref="dialog_card">
<div class="content_1" ref="dialog_header">可拖拽区域</div>
<div>不可拖拽区域</div>
</div>
</div>
</template>
<script>
export default {
name: "custom-clone",
mounted() {
this.dialogMove();
},
methods: {
dialogMove() {
const iframeBox = this.$refs.dialog_card;
const iframeHeader = this.$refs.dialog_header;
console.log(iframeBox, "dialog_card============");
console.log(iframeHeader, "iframeHeader============");
iframeHeader.onmousedown = function (ev) {
// 用元素距离视窗的X、Y坐标,减去el元素最近的相对定位父元素的left、top值
var sX = ev.clientX - iframeBox.offsetLeft;
var sY = ev.clientY - iframeBox.offsetTop;
// 不断地更新元素的left、top值
document.onmousemove = function (ev) {
iframeBox.style.left = ev.clientX - sX + "px";
iframeBox.style.top = ev.clientY - sY + "px";
};
document.onmouseup = function () {
document.onmousemove = null;
document.onmouseup = null;
};
};
},
},
};
</script>
<style lang="less" scoped>
.add_card {
width: 400px;
height: 500px;
border: 1px solid #eff7ff;
background-color: #eff7ff;
position: absolute;
right: 0;
top: 0;
cursor: move;
z-index: 3000;
.content_1 {
height: 100px;
line-height: 100px;
background-color: #0780ed;
}
}
</style>
实现方式2:自定义指令v-drag
drag-min-top设置拖拽上边界,防止拖出可视区域
<template>
<div>
<div class="add_card" ref="dialog_card">
<div class="content_1" v-drag drag-min-top="50" ref="dialog_header">
可拖拽区域drag
</div>
<div>不可拖拽区域</div>
</div>
</div>
</template>
<script>
export default {
name: "custom-clone",
mounted() {
// this.dialogMove();
},
directives: {
drag: {
inserted: function (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;
};
},
},
},
};
</script>
<style lang="less" scoped>
.add_card {
width: 400px;
height: 500px;
border: 1px solid #eff7ff;
background-color: #eff7ff;
position: absolute;
right: 0;
top: 0;
cursor: move;
z-index: 3000;
.content_1 {
height: 100px;
line-height: 100px;
background-color: #0780ed;
}
}
</style>
全局注册方法
1.新建drag.js
import Vue from "vue"
const 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
}
})
export { drag }
2.在入口index.js
引入注册
import {drag} from "@/components/module/OPSScheduleManagement/src/components/common/drag"
Vue.prototype.$drag = drag
3.使用
<template>
<div>
<div class="add_card" ref="dialog_card">
<div class="content_1" v-drag drag-min-top="50" ref="dialog_header">
可拖拽区域drag
</div>
<div>不可拖拽区域</div>
</div>
</div>
</template>
仓库代码地址:容器拖拽
上一篇
input根据关键词过滤
input根据关键词过滤
下一篇
分页组件使用
分页组件使用
版权声明:《 div容器拖拽实现方式 》为胡光喆原创文章,转载请注明出处!
最后编辑:2023-1-30 09:01:52