直接上教科书式代码+注释
<!DOCTYPE html>
<html lang="zh-CN">
<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>多个拖拽</title>
<style>
html,
body {
width: 100%;
height: 100%;
}
.container {
margin: 50px auto;
width: 80%;
height: 80%;
padding: 10px;
background-color: #fdf3a7;
border: 2px solid #fbe961;
box-sizing: border-box;
box-shadow: 0 0 5px #00000080;
}
.start .child {
width: 100px;
height: 50px;
background-color: coral;
border-radius: 5px;
margin-bottom: 10px;
cursor: move;
position: fixed;
}
.child:nth-child(1) {
top: 6%
}
.child:nth-child(2) {
top: 12%
}
.child:nth-child(3) {
top: 18%
}
.child:nth-child(4) {
top: 24%
}
</style>
</head>
<body>
<div class="container">
<div class="start">
<div class="child">1</div>
<div class="child">2</div>
<div class="child">3</div>
<div class="child">4</div>
</div>
</div>
<script>
const start = document.querySelector(".start")
start.addEventListener("mousedown", (event) => {
// 获取鼠标的位置
let x = event.clientX
let y = event.clientY
// getBoundingClientRect() 方法来获取该元素相对于视口(viewport)的位置信息
// 包括左上角的 left 和 top 坐标、右下角的 right 和 bottom 坐标以及宽度和高度等信息
const rect = event.target.getBoundingClientRect()
let ex = rect.left
let ey = rect.top
// 获取视口的宽高
const w = document.documentElement.clientWidth
const h = document.documentElement.clientHeight
// 可移动的空间
const maxLeft = w - rect.width
const maxTop = h - rect.height
// 鼠标按下时监听整个屏幕的鼠标移动
window.onmousemove = function (e) {
// 鼠标移动的距离 = 鼠标实时移动的距离 - 初始鼠标移动的距离
let disX = e.clientX - x
let disY = e.clientY - y
// 实际移动的元素位置 = 元素初始距离 + 鼠标移动的距离
let left = ex + disX,
top = ey + disY
if (left < 0) {
left = 0
} else if (left > maxLeft) {
left = maxLeft
}
if (top < 0) {
top = 0
} else if (top > maxTop) {
top = maxTop
}
event.target.style.left = left + 'px'
event.target.style.top = top + 'px'
}
// 监听整个屏幕的抬起
window.onmouseup = function () {
window.onmousemove = null
window.onmouseup = null
}
})
</script>
</body>
</html>
如果要限制元素只在某一个父级元素方位内移动内
<!DOCTYPE html>
<html lang="zh-CN">
<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>多个拖拽</title>
<style>
html,
body {
width: 99%;
height: 97%;
}
.container {
margin: 50px auto;
width: 80%;
height: 80%;
padding: 10px;
background-color: #fdf3a7;
border: 2px solid #fbe961;
box-sizing: border-box;
box-shadow: 0 0 5px #00000080;
}
.start .child {
width: 100px;
height: 50px;
background-color: coral;
border-radius: 5px;
margin-bottom: 10px;
cursor: move;
position: fixed;
}
.child:nth-child(1) {
top: 6%
}
.child:nth-child(2) {
top: 12%
}
.child:nth-child(3) {
top: 18%
}
.child:nth-child(4) {
top: 24%
}
</style>
</head>
<body>
<div class="container">
<div class="start">
<div class="child">1</div>
<div class="child">2</div>
<div class="child">3</div>
<div class="child">4</div>
</div>
</div>
<script>
const start = document.querySelector(".start")
const container = document.querySelector(".container")
start.addEventListener("mousedown", (event) => {
// 获取鼠标的位置
let x = event.clientX
let y = event.clientY
// getBoundingClientRect() 方法来获取该元素相对于视口(viewport)的位置信息
// 包括左上角的 left 和 top 坐标、右下角的 right 和 bottom 坐标以及宽度和高度等信息
const rect = event.target.getBoundingClientRect()
let ex = rect.left
let ey = rect.top
// 获取视口的宽高
const w = document.documentElement.clientWidth
const h = document.documentElement.clientHeight
// 可移动的空间
const maxLeft = w - rect.width
const maxTop = h - rect.height
// 鼠标按下时监听整个屏幕的鼠标移动
window.onmousemove = function (e) {
// 鼠标移动的距离 = 鼠标实时移动的距离 - 初始鼠标移动的距离
let disX = e.clientX - x
let disY = e.clientY - y
// 实际移动的元素位置 = 元素初始距离 + 鼠标移动的距离
let left = ex + disX,
top = ey + disY
// 如果要限制元素只在某一个元素方位内移动内
const location = container.getBoundingClientRect()
const locationX = location.left
const locationY = location.top
const locationR = w - location.width - locationX
const locationB = h - location.height - locationY
// 鼠标距离左面移动最小值 = 父级盒子距离左侧的距离
if (left < locationX) {
left = locationX
// 鼠标距离右面移动最小值 = 鼠标移动最大值 - 元素右侧距离屏幕右侧的距离
} else if (left > maxLeft - locationR) {
left = maxLeft - locationR
}
if (top < 0 + locationY) {
top = locationY
} else if (top > maxTop - locationB) {
top = maxTop - locationB
}
event.target.style.left = left + 'px'
event.target.style.top = top + 'px'
}
// 监听整个屏幕的抬起
window.onmouseup = function () {
window.onmousemove = null
window.onmouseup = null
}
})
</script>
</body>
</html>