注释可能不够详细,代码写的有点多,效果基本全部实现了。
记录定位值以及clientX,Y值和offsetX,Y值是关键
<!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>
* {
margin: 0;
padding: 0;
/* cursor: e-resize; */
}
#parent {
width: 100%;
height: 600px;
background: pink;
position: relative;
}
#son {
width: 200px;
height: 200px;
background: orange;
position: absolute;
}
</style>
</head>
<body>
<div id="parent">
<div id="son"></div>
</div>
<script>
var parent = document.getElementById('parent');
var son = document.getElementById('son');
//保存值,以用于判断
var _Text = '';
//记录子级盒子点击的X点坐标
var cliX = 0;
//记录子级盒子点击的Y点坐标
var cliY = 0;
//记录子级盒子的宽
var cliW = 0;
//记录子级盒子的高
var cliH = 0;
//通过父级滑动事件触发子盒子移动
parent.onmousemove = function (e) {
//switch语句判断鼠标点击在什么位置
switch (true) {
//点击的位置在子级中间时执行移动操作
case _Text == 'center':
//记录盒子当前位置的距离左边与上边的距离
var yunLeft = e.clientX - cliX;
var yuntop = e.clientY - cliY;
//进行判断,以此确定边界值
if (yunLeft <= 0) {
yunLeft = 0;
}
if (yunLeft >= parent.offsetWidth - son.offsetWidth) {
yunLeft = parent.offsetWidth - son.offsetWidth;
}
if (yuntop <= 0) {
yuntop = 0;
}
if (yuntop >= parent.offsetHeight - son.offsetHeight) {
yuntop = parent.offsetHeight - son.offsetHeight;
}
son.style.left = yunLeft + 'px';
son.style.top = yuntop + 'px';
break;
//点击的位置在子盒子右边界时执行的操作
case _Text == 'right':
//因为是去做拉宽盒子的动作,所以只需要确定盒子的宽度即可。
son.style.width = e.clientX - son.offsetLeft + 'px'
break;
//点击的位置在子盒子下边界时执行的操作
case _Text == 'bottom':
//因为是去做拉高盒子的动作,所以只需要确定盒子的高度即可。
son.style.height = e.clientY - son.offsetTop + 'px'
break;
//点击的位置在子盒子左边界时执行的操作
case _Text == 'left':
//因为往左拉宽子级的时候,需要加上子级原来的宽。所以这里就用到了上面记录的宽;
//往左拉伸的时候,子级的clientX会越来越少,所以通过原来点击的值减去现在的X值,就可以求出子级变宽了多少
son.style.width = (cliX - e.clientX) + cliW + 'px';
son.style.left = e.clientX + 'px';
break;
//点击的位置在子盒子上边界时执行的操作
case _Text == 'top':
//因为往上拉宽子级的时候,需要加上子级原来的高。所以这里就用到了上面记录的高;
//往上拉伸的时候,子级的clientY会越来越少,所以通过原来点击的值减去现在的Y值,就可以求出子级变高了多少
son.style.height = (cliY - e.clientY) + cliH + 'px';
son.style.top = e.clientY + 'px';
break;
//点击的位置在子盒子左上边界时执行的操作
case _Text == 'zuoshang':
//左上拉伸的时候,高和宽都需要做出改变,所以在这里调用的是左边界和上边界的逻辑
son.style.width = (cliX - e.clientX) + cliW + 'px';
son.style.left = e.clientX + 'px';
son.style.height = (cliY - e.clientY) + cliH + 'px';
son.style.top = e.clientY + 'px';
break;
//点击的位置在子盒子左下边界时执行的操作
case _Text == 'zuoxia':
//这里调用的是左边界和下边界的逻辑
son.style.width = (cliX - e.clientX) + cliW + 'px';
son.style.left = e.clientX + 'px';
son.style.height = e.clientY - son.offsetTop + 'px'
break;
//点击的位置在子盒子右上边界时执行的操作
case _Text == 'youshang':
//这里调用的是右边界和上边界的逻辑
son.style.width = e.clientX - son.offsetLeft + 'px';
son.style.height = (cliY - e.clientY) + cliH + 'px';
son.style.top = e.clientY + 'px';
break;
//点击的位置在子盒子右下边界时执行的操作
case _Text == 'youxia':
//这里调用的是右边界和下边界的逻辑
son.style.width = e.clientX - son.offsetLeft + 'px';
son.style.height = e.clientY - son.offsetTop + 'px';
break;
}
}
//当点击子级时做的操作
son.onmousedown = function (e) {
//接受函数的返回值,以确定进行什么操作
var jieShou = jiLu(e.offsetX, e.offsetY, e.target.offsetWidth, e.target.offsetHeight);
switch (true) {
//点击的为中间时执行的操作;
case jieShou == 'center':
//改变值,以执行上边的操作
_Text = 'center';
//改变鼠标样式
son.style.cursor = 'move';
//记录点击时的offsetX与offsetY值
cliX = e.offsetX;
cliY = e.offsetY;
break;
//点击为右边界时执行的操作
case jieShou == 'right':
_Text = 'right';
son.style.cursor = 'e-resize';
break;
//点击为下边界时执行的操作
case jieShou == 'bottom':
_Text = 'bottom';
son.style.cursor = 's-resize';
break;
//点击为左边界时执行的操作
case jieShou == 'left':
_Text = 'left';
son.style.cursor = 'e-resize';
//记录点击时的clientX值与盒子的宽度。
cliX = e.clientX;
cliW = e.target.offsetWidth;
break;
//点击为上边界时执行的操作
case jieShou == 'top':
_Text = 'top';
son.style.cursor = 's-resize';
//记录点击时的clientY值与盒子的高度。
cliY = e.clientY;
cliH = e.target.offsetHeight;
break;
//点击为左上边界时执行的操作
case jieShou == 'zuoshang':
_Text = 'zuoshang';
son.style.cursor = 'se-resize';
//调用左边界和上边界的逻辑
cliY = e.clientY;
cliX = e.clientX;
cliH = e.target.offsetHeight;
cliW = e.target.offsetWidth;
break;
//点击为左下边界时执行的操作
case jieShou == 'zuoxia':
_Text = 'zuoxia';
son.style.cursor = 'ne-resize';
//调用左边界和下边界的逻辑
cliY = e.clientY;
cliX = e.clientX;
cliH = e.target.offsetHeight;
cliW = e.target.offsetWidth;
break;
//点击为右上边界时执行的操作
case jieShou == 'youshang':
_Text = 'youshang';
son.style.cursor = 'ne-resize';
cliY = e.clientY;
cliX = e.clientX;
cliH = e.target.offsetHeight;
cliW = e.target.offsetWidth;
break;
//点击为右下边界时执行的操作
case jieShou == 'youxia':
_Text = 'youxia';
son.style.cursor = 'se-resize';
cliY = e.clientY;
cliX = e.clientX;
cliH = e.target.offsetHeight;
cliW = e.target.offsetWidth;
break;
}
}
//当鼠标松开的时候进行的操作
parent.onmouseup = function (e) {
_Text = '';
cliX = 0;
cliY = 0;
son.style.cursor = '';
cliW = 0;
cliH = 0;
}
//通过这个函数以记录鼠标点到什么位置时返回对应的值
function jiLu(x, y, w, h) {
switch (true) {
case (x < 10 && y < 10):
return 'zuoshang';
case (x > w - 10 && y < 10):
return 'youshang';
case (x > w - 10 && y > h - 10):
return 'youxia';
case (x < 10 && y > h - 10):
return 'zuoxia'
case x < 10:
return 'left';
case x > w - 10:
return 'right';
case y < 10:
return 'top';
case y > h - 10:
return 'bottom';
default:
return 'center';
}
}
</script>
</body>
</html>