[TOC]
### 效果展示:
![](http://elb-791125809.cn-northwest-1.elb.amazonaws.com.cn:5335/xdata/xdata-sh-firstdept/front-end/note-book/raw/ca3fe1a8a3999133d8071bcad13c7f2f16965460/%E5%AD%90%E5%85%83%E7%B4%A0%E5%9C%A8%E5%AE%B9%E5%99%A8%E8%8C%83%E5%9B%B4%E5%86%85%E6%8B%96%E5%8A%A8/.image/1.gif)
### 实现思路:
~~~
找一个空箱子和一块小于箱子纸板,用笔插穿纸板,然后在箱子里面笔在箱底随便画,能画出的的范围肯定是有限的;
容器相当于箱子,子元素相当于纸板,鼠标位置相当于笔,然后就有了鼠标能移动的范围
~~~
### 实现原理:
~~~
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
<style>
html,body,.father {margin: 0;height: 100%;width: 100%;}
body{display: flex;justify-content: center; align-items: center;}
.contain{ position: relative; height: 90%;width: 90%;border: black 1px solid;background-color: rgba(205, 135, 222, 0.767);}
.child {position: absolute;height: 200px;width: 200px;border: black 1px solid;background-color: coral;}
</style>
</head>
<body>
<div class="contain">
<div id="father" class="father">
<div
id="child"
class="child"
onmousedown="mouseDown(event)"
></div>
</div>
</div>
<script>
let child = document.querySelector('#child')
const mouseDown = evt => {
let mBounds = mouseBounds(
evt,
child.getBoundingClientRect(),
document.querySelector('#father').getBoundingClientRect()
)
document.onmousemove = function(ev) {
let pt = calcPositon(ev, mBounds)
child.style.left = pt.left + 'px'
child.style.top = pt.top + 'px'
child.style.opacity = 0.9
child.style.cursor = 'move'
}
document.onmouseup = function() {
document.onmousemove = null
document.onmouseup = null
child.style.opacity = 1
child.style.cursor = 'default'
}
}
const calcPositon = (pt, bounds) => {
const left =
(pt.x > bounds.left && pt.x < bounds.right
? pt.x
: pt.x >= bounds.right
? bounds.right
: bounds.left) - bounds.offsetX
const top =
(pt.y > bounds.top && pt.y < bounds.bottom
? pt.y
: pt.y >= bounds.bottom
? bounds.bottom
: bounds.top) - bounds.offsetY
return { left, top }
}
/**
* 鼠标可以移动的范围
* pt:鼠标按下的点
* compRact:要移动组件的矩形对象
* containerRact:容器的矩形对象
* return 的范围为浏览器窗口中的范围(offset为左上角相对于浏览器的偏移)
*/
const mouseBounds = (pt, compRact, containerRact) => {
return {
left: containerRact.left + (pt.x - compRact.left),
right: containerRact.right - (compRact.right - pt.x),
top: containerRact.top + (pt.y - compRact.top),
bottom: containerRact.bottom - (compRact.bottom - pt.y),
offsetX: containerRact.left + (pt.x - compRact.left),
offsetY: containerRact.top + (pt.y - compRact.top)
}
}
</script>
</body>
</html>
~~~