原生JavaScript元素拖拽缩放
效果
使用方法
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<link rel="stylesheet" href="./dragSize.css">
<style>
.box {
width: 300px;
height: 300px;
background: gray;
}
</style>
</head>
<body>
<div class="box"></div>
</body>
<script src="./dragSize.js" mod></script>
<script>
let box = document.querySelector('.box');
dragSize(box, {
delay: 10
});
</script>
</html>
.dragSize {
position: relative;
}
.dragSize .dragSizeItem {
position: absolute;
}
.dragSize .dragSizeItem-across {
right: 0px;
top: 0px;
width: 5px;
height: 100%;
cursor: e-resize;
}
.dragSize .dragSizeItem-vertical {
left: 0px;
bottom: 0px;
width: 100%;
height: 5px;
cursor: s-resize;
}
.dragSize .dragSizeItem-slant {
right: 0px;
bottom: 0px;
width: 10px;
height: 10px;
cursor: se-resize;
}
function dragSize(el, {
across = true,
vertical = true,
slant = true,
delay = 20,
position = 'relative'
} = {
}) {
el.classList.add('dragSize');
el.style.position = position;
if (across) {
addDrag('across');
}
if (vertical) {
addDrag('vertical');
}
if (slant) {
addDrag('slant');
}
let pos = {
startX: 0,
startY: 0,
startWidth: 0,
startHeight: 0,
}
function addDrag(direct) {
let dragItem = document.createElement('div');
dragItem.className = 'dragSizeItem dragSizeItem-' + direct;
el.append(dragItem);
let moveEvent = throttle((e) => {
if (direct == 'across') {
el.style.width = pos.startWidth + (e.pageX - pos.startX) + 'px';
}
if (direct == 'vertical') {
el.style.height = pos.startHeight + (e.pageY - pos.startY) + 'px';
}
if (direct == 'slant') {
el.style.width = pos.startWidth + (e.pageX - pos.startX) + 'px';
el.style.height = pos.startHeight + (e.pageY - pos.startY) + 'px';
}
}, delay)
dragItem.addEventListener('mousedown', (startEvent) => {
pos.startX = startEvent.pageX;
pos.startY = startEvent.pageY;
pos.startWidth = el.offsetWidth;
pos.startHeight = el.offsetHeight;
document.addEventListener('mousemove', moveEvent);
document.addEventListener('mouseup', (endEvent) => {
document.removeEventListener('mousemove', moveEvent);
})
})
}
}
function throttle(cb, time) {
let lock = false;
return function(e) {
if (lock) {
return;
}
lock = true;
cb(e);
setTimeout(() => {
lock = false;
}, time);
}
}
大致思路
- 给
el
元素添加三个div分别对应红绿蓝代表拖拽操作区域,cursor: e-resize;
可切换鼠标指针
- 给三个div绑定鼠标
down、move、up
事件模拟拖拽效果
- 计算每次拖拽
起始点
与结束点
的距离赋值给el
容器的width和height
- 注意节流优化