<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
#box {
top: 100px;
left: 200px;
position: absolute;
border: 5px solid #000;
width: 10px;
height: 10px;
border-top-color: aqua;
}
body {
margin: 0;
width: 100%;
height: 100vh;
}
</style>
</head>
<body>
<div id="box"></div>
<script>
const odiv = document.getElementById('box');
new BoxHandler(odiv);
function BoxHandler(e) {
this.element = e;//实例对象
this.width = e.clientWidth;//对象宽
this.height = e.clientHeight;//对象高
this.top = e.offsetTop;//距离高
this.left = e.offsetLeft;//距离左
this.isChange = false;//是否处于拖拽状态
this.borderWidth = e.clientLeft
this.borderTop = e.clientTop
//目前鼠标相对于盒子的位置 0-8
this.whereCursor = {
x: '',
y: '',
toString() {
return `${this.x}_${this.y}`
}
};
//点击时鼠标相对于盒子的位置 0-8
this.whereCursorClick = {
x: '',
y: '',
toString() {
return `${this.x}_${this.y}`
}
};
//是否反转
this.isDefeat = {
x: false,
y: false
}
//鼠标样式定义表
const cursorMapping = {
"no_no": 'auto',//鼠标在内部
"left_no": 'e-resize',//鼠标在左
"right_no": 'e-resize',//鼠标在右
"no_top": 'n-resize',//鼠标在上
"left_top": 'se-resize',//鼠标在左上
"right_bottom": 'sw-resize',//鼠标在右上
"no_bottom": 'n-resize',//鼠标在下
"left_bottom": 'sw-resize',//鼠标在左下
"right_bottom": 'se-resize',//鼠标在右下
}
document.addEventListener("mousemove", (event) => {
const { pageX, pageY, offsetX, offsetY } = event;//结构出鼠标位置
if (event.target === this.element) { //解决鼠标样式异常问题
this.whereCursor.x = offsetX <= 0 ? 'left' : offsetX >= this.width ? 'right' : 'no'; //左1 右2 其它0
this.whereCursor.y = offsetY <= 0 ? 'top' : offsetY >= this.height ? 'bottom' : 'no'; //上1 下2 其它0
//设置鼠标样式
this.setCursor(cursorMapping[this.whereCursor.toString()]);
}
if (this.isChange) {
//获取鼠标相对位置变化
const rX = pageX - this.cursorX;
const rY = pageY - this.cursorY;
if (this.whereCursorClick.toString() === 'no_no') {
//触发拖拽
this.setLeftTopPointRXY(rX, rY);
} else {
const xHandler = (() => {
if (this.isDefeat.x) {
if (this.whereCursorClick.x === 'left') {
return 'right'
} else {
return 'left'
}
} else {
return this.whereCursorClick.x
}
})();
const yHandler = (() => {
if (this.isDefeat.y) {
if (this.whereCursorClick.y === 'top') {
return 'bottom'
} else {
return 'top'
}
} else {
return this.whereCursorClick.y
}
})();
//操作
switch (xHandler) {
case 'left':
this.setLeftTopPointRXY(rX, 0);
this.setBoxRXY(-rX, 0);
break;
case 'right':
this.setBoxRXY(rX, 0);
break;
}
switch (yHandler) {
case 'top':
this.setLeftTopPointRXY(0, rY);
this.setBoxRXY(0, -rY);
break;
case 'bottom':
this.setBoxRXY(0, rY);
break;
}
}
this.cursorX = pageX;
this.cursorY = pageY;
}
})
//左键点击事件
this.element.addEventListener("mousedown", (event) => {
if (event.button != 0) return;//监听鼠标左键
//记录当前鼠标位置
const { pageX, pageY } = event;
this.cursorX = pageX;
this.cursorY = pageY;
//记录当前状态
this.whereCursorClick.x = this.whereCursor.x;
this.whereCursorClick.y = this.whereCursor.y;
this.isChange = true;//开始拖拽状态
})
//鼠标松开事件
document.addEventListener("mouseup", (event) => {
if (event.button != 0) return; //监听鼠标左键
if (!this.isChange) return;
this.isChange = false;//关闭拖拽状态
this.isDefeat = { x: false, y: false };//初始化反转
})
//设置鼠标样式
this.setCursor = (str) => {
this.element.style.cursor = str;
};
//设置位置
this.setLeftTopPointRXY = (x, y) => {
//解决微小偏差的BUG
if (this.width > 0 || (this.width == 0 && x < 0)) this.left += x;
if (this.height > 0 || (this.height == 0 && y < 0)) this.top += y;
this.element.style.top = this.top + "px";
this.element.style.left = this.left + "px";
};
//设置宽高
this.setBoxRXY = (x, y) => {
this.width += x;
this.height += y;
if (this.width <= -this.borderWidth) {
this.isDefeat.x = !this.isDefeat.x;//开启反转
this.width = 0;
}
if (this.height <= -this.borderTop) {
this.isDefeat.y = !this.isDefeat.y;//开启反转
this.height = 0;
}
this.element.style.width = this.width + "px";
this.element.style.height = this.height + "px";
};
}
</script>
</body>
</html>