vue2精简方式实现鼠标在方框内拖拽效果源码

简介: vue2精简方式实现鼠标在方框内拖拽效果源码

vue2精简方式实现鼠标在方框内拖拽效果原理,含源码
前言:最终效果如图如下:
原理如下:
html和css代码结构:
js代码结构介绍:
完整代码如下:
前言:最终效果如图如下:
鼠标在橙色盒子上按下,可同时拖拽橙色和灰色盒子在大方框中移动,盒子不会超出方框范围。松开鼠标即停止拖动。

鼠标在灰色盒子上按下,可拖动灰色盒子在橙色盒子中移动,灰色盒子不会超出橙色盒子范围,鼠标松开即停止拖动

原理如下:
分别监听橙色盒子和灰色盒子的鼠标按下事件,在鼠标按下的那一刹那,将鼠标的“鼠标x”,“鼠标y”坐标保存下来,使用offsetLeft和offsetTop属性算出鼠标在盒子中的位置x,y,鼠标移动的时候,鼠标在盒子中的位置x,y不变,用鼠标的“鼠标x”,“鼠标y”减去鼠标在盒子中的位置x,y,就是盒子移动的距离,根据盒子移动的距离,来设置盒子的left和top距离,就可以随意的控制盒子的位置(盒子必须是position: absolute定位),这样就可以实现鼠标拖动盒子移动的效果了。

(本案例中是两个盒子都可以移动,原理同上,跟一个盒子原理一样。本案例中是将灰色小盒子的鼠标按下事件mousedown代理给了橙色大盒子,所以只需要绑定一个mousedown事件,就分别可以监听两个盒子的mousedown事件,并在js方法中通过e.target区分两个盒子,实际上还是监听了两个盒子的mousedown)

html和css代码结构:
html结构:

// 黑色大方框
// 橙色盒子
// 灰色盒子


// 给middle-box橙色盒子绑定鼠标按下事件@mousedown(此处使用事件冒泡特性,将small-box灰色盒子的鼠标按下事件,通过冒泡的方式代理给橙色盒子,
// 这样只绑定了一个事件,就可以监听到2个盒子的鼠标按下事件,使用e.target属性区分两个盒子)

css:
.program {
position: relative;
margin: 30px auto;
width: 400px;
height: 400px;
text-align: center;
border: 1px solid #000;
.middle-box {
position: absolute;
left: 0;
top: 0;
width: 100px;
height: 100px;
background-color: rgb(255, 160, 93);
.small-box {
position: absolute;
left: 0;
top: 0;
width: 50px;
height: 50px;
background-color: #646464;
}
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
js代码结构介绍:
页面挂载完之后,获取黑色大方框盒子的信息,存储在bigBox变量中。
在middleDown方法中使用e.target.className === ‘middle-box’,来判断当前按下的是橙色盒子还是黑色盒子(middle-box为橙色盒子),使用flag变量来记录当前点击的盒子。
如果是点击橙色盒子,就把橙色盒子的信息存进box中,如果是点击灰色盒子,就把灰色盒子的信息存进box中,方便后续使用。
data () {
return {
bigBox: null,
x: 0,
y: 0,
flag: true
}
},
mounted () {
this.bigBox = this.$refs.bigBox;
},
methods: {
middleDown (e) {
console.dir(this.bigBox, 'console.dir============');
console.log(this.bigBox, 'console.log============');
this.flag = e.target.className === 'middle-box';
const box = this.flag ? this.bigBox.children[0] : this.bigBox.children[0].children[0]
this.x = e.x - box.offsetLeft;
this.y = e.y - box.offsetTop;
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
通过console.dir打印的控制台信息可以看到,元素对象上都会有offsetLeft和offsetTop属性

用e.x - box.offsetLeft, e.y - box.offsetTop,分别求出下图中,横向两条绿色线,和竖向两条绿色线加起来的长度,存在x和y中。

[注] :使用console.dir()可以打印出元素对象的详细信息,使用console.log只能打印简略信息。但console.dir()只会打印括号中的第一个内容。

在middleDown方法中监听页面的鼠标移动mousemove和页面的鼠标弹开mouseup事件。
在鼠标移动事件mousemove里面根据鼠标e.x和e.y移动的距离,分别设置盒子的左右边距(盒子必须是position: absolute定位,通过设置盒子的left和top来控制盒子的位置)来实现盒子跟着鼠标移动。
在鼠标弹开事件mouseup中,结束监听mousemove事件,此时盒子固定在当前位置上,不在跟随鼠标移动,实现鼠标弹起时停止拖拽的效果。
methods: {
middleDown (e) {
console.dir(this.bigBox, 'console.dir============');
console.log(this.bigBox, 'console.log============');
this.flag = e.target.className === 'middle-box';
const box = this.flag ? this.bigBox.children[0] : this.bigBox.children[0].children[0]
this.x = e.x - box.offsetLeft;
this.y = e.y - box.offsetTop;
// console.dir(this.bigBox.children[0], '2');
window.addEventListener('mousemove', this.mouseMove)
window.addEventListener('mouseup', this.middleUp)
},
middleUp () {
window.removeEventListener('mousemove', this.mouseMove)
},
mouseMove (e) {
setTimeout(() => {
const maxNam = this.flag ? 300 : 50;
const box = this.flag ? this.bigBox.children[0] : this.bigBox.children[0].children[0]
const moveX = (e.x - this.x) >= maxNam ? maxNam : ((e.x - this.x) <= 0 ? 0 : (e.x - this.x))
const moveY = (e.y - this.y) >= maxNam ? maxNam : ((e.y - this.y) <= 0 ? 0 : (e.y - this.y))
box.style.left = moveX + 'px';
box.style.top = moveY + 'px';
}, 50);
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
在mouseMove事件中,首先应设置节流阀节省性能,使用setTimeout方法50毫秒执行一次位置赋值操作,给盒子设置新的位置(毫秒数根据自己情况调节)
为了不超出外围盒子,设置maxNam为橙色或灰色盒子移动的最大距离,如下图所示:橙色大盒子上下左右移动的最大距离为0-300px,灰色小盒子上下左右移动的最大距离为0-50px。
用e.x - this.x算出盒子应跟着鼠标移动的距离,如果小于0,就设置移动距离为0。如果大于300或50,就设置移动距离为300或50,然后把移动的距离赋值给盒子的left和top,实现盒子在框里面移动。

完整代码如下:







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
文章知识点与官方知识档案匹配,可进一步学习相关知识
Vue入门技能树Vue2响应式检测变化43552 人正在系统学习中

陈架的小跟班
关注

42

56

0

关于我们
招贤纳士
商务合作
寻求报道

400-660-0108

[email protected]

在线客服
工作时间 8:30-22:00
公安备案号11010502030143
京ICP备19004658号
京网文〔2020〕1039-165号
经营性网站备案信息
北京互联网违法和不良信息举报中心
家长监护
网络110报警服务
中国互联网举报中心
Chrome商店下载
账号管理规范
版权与免责声明
版权申诉
出版物许可证
营业执照
©1999-2024北京创新乐知网络技术有限公司
目录
vue2精简方式实现鼠标在方框内拖拽效果原理,含源码
前言:最终效果如图如下:
原理如下:
html和css代码结构:
js代码结构介绍:
完整代码如下:

相关文章
|
JavaScript
【vue】 vue2 自定义指令 实现全屏 、对话框拖拽
【vue】 vue2 自定义指令 实现全屏 、对话框拖拽
515 2
|
JavaScript
基于Vue2或Vue3实现任意上下左右拖拽悬浮的元素,且配置为自定义的全局指令
这篇文章介绍了如何在Vue 2或Vue 3项目中实现一个自定义的全局指令`v-dragSwitch`,用于创建可以任意方向拖拽并悬浮的元素,同时包含边界处理的逻辑。
4028 2
基于Vue2或Vue3实现任意上下左右拖拽悬浮的元素,且配置为自定义的全局指令
|
9月前
|
iOS开发 开发者 Windows
uniapp云打包ios应用证书的获取方法,生成指南
打包用到的一共两个文件,一个是p12格式的私钥证书,一个是证书profile文件。其中生成p12证书的时候,按照官网的教程,是需要MAC电脑来协助做的,主要是生成一些csr文件和导出p12证书等。其实这些步骤也可以借助一些其他的工具来实现,不一定使用mac电脑,用windows电脑也可以创建。
1215 0
|
移动开发 资源调度 JavaScript
【Vue 2】一个高效的低代码表单,可视化设计,一键生成源码,享受更多摸鱼时间!!
【Vue 2】一个高效的低代码表单,可视化设计,一键生成源码,享受更多摸鱼时间!!
|
资源调度 JavaScript
Vue2拖拽插件(vuedraggable)
这篇文章介绍了如何在Vue 3框架中使用`vuedraggable`插件来实现拖拽功能,并提供了插件的安装、配置和事件处理的示例。
1338 1
Vue2拖拽插件(vuedraggable)
springCloud之服务降级熔断Hystrix、OpenFeign
springCloud之服务降级熔断Hystrix、OpenFeign
1177 0
|
JavaScript
vue自定义v-drag指令实现鼠标拖拽
vue自定义v-drag指令实现鼠标拖拽
669 2
|
JavaScript 前端开发
多种模块格式,包括 ES, CommonJS, UMD, AMD, SystemJS 和 IIFE的区别点分别是什么?
【10月更文挑战第20天】在实际应用中,选择合适的模块格式需要根据项目的需求、目标环境以及开发团队的习惯等因素来综合考虑。不同的模块格式都有其自身的优势和适用场景,合理选择可以提高代码的组织性、可维护性和性能。
520 8
|
资源调度 JavaScript 前端开发
vue-element-admin 综合开发一:搭建环境:vue-cli创建项目,整合element、vue-router
这篇文章是关于如何使用vue-cli搭建vue环境,并整合Element UI和vue-router来开发一个基础的前端管理后台界面。
482 0
vue-element-admin 综合开发一:搭建环境:vue-cli创建项目,整合element、vue-router
|
存储 JavaScript UED
在 Vue 组件中动态切换全局样式
【10月更文挑战第5天】
322 1

热门文章

最新文章