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

kefu@csdn.net

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

相关文章
vue2实现markdown编辑器,实现同步滚动,实时预览等功能
vue2实现markdown编辑器,实现同步滚动,实时预览等功能
|
1月前
|
JavaScript
基于Vue2或Vue3实现任意上下左右拖拽悬浮的元素,且配置为自定义的全局指令
这篇文章介绍了如何在Vue 2或Vue 3项目中实现一个自定义的全局指令`v-dragSwitch`,用于创建可以任意方向拖拽并悬浮的元素,同时包含边界处理的逻辑。
279 2
基于Vue2或Vue3实现任意上下左右拖拽悬浮的元素,且配置为自定义的全局指令
|
1月前
|
前端开发
前端ElementPlus框架中的几种图标按钮使用方式
本文介绍了如何在Element Plus前端框架中使用带有图标的按钮,包括设置按钮大小、图标大小、按钮类型以及如何为图标添加点击事件。
144 0
|
2月前
|
存储 容器
vue3【实战】来回拖拽放置图片
vue3【实战】来回拖拽放置图片
66 2
|
3月前
|
JavaScript
如何实现vue点击按钮进行图片浏览 ?
如何实现vue点击按钮进行图片浏览 ?
|
2月前
|
JavaScript 前端开发
vue 富文本编辑器 quill (含代码高亮、自定义字体、汉化、鼠标悬浮提示、组件封装等)
vue 富文本编辑器 quill (含代码高亮、自定义字体、汉化、鼠标悬浮提示、组件封装等)
87 0
|
2月前
|
容器
Vite项目当中的SVG图标的配置及图标全局组件的封装
Vite项目当中的SVG图标的配置及图标全局组件的封装
68 0
|
4月前
|
JavaScript
vue中多组件调用,实现上下分屏,上下拖动
vue中多组件调用,实现上下分屏,上下拖动
158 0
|
4月前
|
JavaScript 定位技术 API
OpenLayers入门-第二篇、在vue3中使用elementplus制作图层控件,图层切换,显示隐藏,图层排序
OpenLayers入门-第二篇、在vue3中使用elementplus制作图层控件,图层切换,显示隐藏,图层排序
107 1
|
4月前
|
定位技术
vue3制作地图,可接口,图标可调
vue3制作地图,可接口,图标可调
50 0