鼠标拖拽盒子移动

目录

需求

浮动的盒子添加鼠标拖拽功能

思路

  1. 给需要拖动的盒子添加鼠标按下事件
  2. 鼠标按下后获取鼠标点击位置与盒子边缘的距离
  3. 给 document 添加鼠标移动事件
  4. 鼠标移动过程中,将盒子的位置进行重新定位
  5. 侦听 document 鼠标弹起,移除鼠标移动事件

代码

html 复制代码
<!-- 鼠标拖拽盒子 -->
<template>
  <div>
    <!-- 【1】给需要拖动的盒子添加鼠标按下事件 -->
    <div ref="btns" class="btns" @mousedown="mousedownHandler">试试拖动我</div>
  </div>
</template>

<script>
export default {
  name: 'Drag',
  components: {},

  data() {
    return {
      mouseToBoxRangeX: 0, // 鼠标点击位置与盒子边缘的距离
      mouseToBoxRangeY: 0 // 鼠标点击位置与盒子边缘的距离
    }
  },

  computed: {},

  watch: {},

  mounted() {
    // 【5】侦听 document 鼠标弹起,移除鼠标移动事件
    document.addEventListener('mouseup', () => {
      document.removeEventListener('mousemove', this.mousemoveHandler)
    })
  },

  methods: {
    mousedownHandler($event) {
      // 【2】鼠标按下后获取鼠标点击位置与盒子边缘的距离
      //  鼠标点击位置与盒子边缘的距离 = 鼠标点击位置 - 盒子当前位置
      this.mouseToBoxRangeX = $event.pageX - this.$refs.btns.offsetLeft
      this.mouseToBoxRangeY = $event.pageY - this.$refs.btns.offsetTop
      // 【3】给 document 添加鼠标移动事件
      document.addEventListener('mousemove', this.mousemoveHandler)
    },
    mousemoveHandler($event) {
      // 【4】鼠标移动过程中,将盒子的位置进行重新定位
      // 盒子当前位置 = 鼠标点击位置 - 鼠标点击位置与盒子边缘的距离 - 盒子自身设定的边距(此处没有)
      // 【注意】设置盒子最新位置时需加上单位 'px'
      this.$refs.btns.style.left = $event.pageX - this.mouseToBoxRangeX + 'px'
      this.$refs.btns.style.top = $event.pageY - this.mouseToBoxRangeY + 'px'
    }
  }
}
</script>

<style lang='scss' scoped>
.btns {
  width: 70px;
  height: 147px;
  position: absolute;
  bottom: 10px;
  right: 10px;
  z-index: 2000;
  cursor: move;
  background-color: red;
}
</style>

页面展示

【补充】纯js实现

html 复制代码
<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8" />
		<meta http-equiv="X-UA-Compatible" content="IE=edge" />
		<meta name="viewport" content="width=device-width, initial-scale=1.0" />
		<title>Document</title>
		<style>
			* {
				margin: 0;
				padding: 0;
			}

			.box {
				position: relative;
				width: 100px;
				height: 100px;
				background-color: tomato;
				margin: 100px;
			}
		</style>
	</head>

	<body>
		<div class="box"></div>
		<script>
			/* 
		        效果:鼠标拖着盒子移动
		        拖着:
		            鼠标左键按着不松手(mousedown),然后鼠标移动(mousemove)
		        注意:鼠标左键按下,才注册上了鼠标移动事件
	        */
			var box = document.querySelector('.box')

			// 添加鼠标点击事件
			box.addEventListener('mousedown', function (e) {
				console.log('this----', this)
				console.log('this.offsetLeft----', this.offsetLeft)
				console.log('this.offsetTop----', this.offsetTop)
				// 【1】获取鼠标在盒子里的位置
				// 鼠标的坐标 - 盒子的坐标
				var x = e.pageX - this.offsetLeft
				var y = e.pageY - this.offsetTop
				console.log(x, y)

				// 注册鼠标移动事件(给整个document添加 事件)
				document.addEventListener('mousemove', move)

				function move(e) {
					// 【2】设置盒子的位置(注意 给盒子添加定位)
					// 鼠标的坐标 - 鼠标在盒子里的坐标
					// 【2.1】盒子没有外边距
					// box.style.left = (e.pageX - x) + 'px';
					// box.style.top = (e.pageY - y) + 'px';

					// 【2.2】盒子有外边距
					box.style.left = e.pageX - x - 100 + 'px'
					box.style.top = e.pageY - y - 100 + 'px'
				}
				// 【3】鼠标弹起,删除移动事件
				document.addEventListener('mouseup', function () {
					// 删除鼠标移动事件
					document.removeEventListener('mousemove', move)
				})
			})
		</script>
	</body>
</html>
相关推荐
kyriewen1 小时前
别再 console.log 了:5 个 Chrome DevTools 调试技巧,用过就回不去了
前端·javascript·面试
To_OC3 小时前
LC 1 两数之和:面试第一道必考题,暴力解法直接被面试官 pass
javascript·算法·leetcode
GuWenyue4 小时前
排序效率低?5分钟吃透快速排序,性能飙升至O(nlogn)
前端·javascript·面试
何时梦醒5 小时前
深入理解递归与快速排序 —— 从基础入门到手写实现
前端·javascript
bonechips5 小时前
LLM 的无状态:从 HTTP 协议到对话上下文工程
前端·javascript
胡志辉5 小时前
从 prototype 到 V8,看懂 JavaScript 原型链
前端·javascript
ping某6 小时前
专栏-null 和 undefined 到底是什么?
前端·javascript·后端
swipe9 小时前
从 0 到 1 理解 React 虚拟列表:定高、不定高与 Canvas 版本完整拆解
前端·javascript·面试
铁皮饭盒10 小时前
Bun执行python代码
前端·javascript·后端
zzzzzz31012 小时前
当甲方说'logo放大的同时再缩小一点'时,我用 AI 把这个需求做出来了
javascript·css·程序员