原生JavaScript元素拖拽缩放

原生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>
/* css文件 */
.dragSize {
    
    
		position: relative;
}
.dragSize .dragSizeItem {
    
    
	position: absolute;
}
.dragSize .dragSizeItem-across {
    
    
	right: 0px;
	top: 0px;
	width: 5px;
	height: 100%;
	cursor: e-resize;
	/* background-color: red; */
}
.dragSize .dragSizeItem-vertical {
    
    
	left: 0px;
	bottom: 0px;
	width: 100%;
	height: 5px;
	cursor: s-resize;
	/* background-color: green; */
}
.dragSize .dragSizeItem-slant {
    
    
	right: 0px;
	bottom: 0px;
	width: 10px;
	height: 10px;
	cursor: se-resize;
	/* background-color: blue; */
}
/**
 * 
 * @param {*} el 
 * @param {
	 across   能否横向拖动
	 vertical 能否纵向拖动
	 slant    能否斜向拖动
	 delay    延迟时间
	 position 父元素定位方式
 } options 
 */

// 这里没用Es6的import
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
  • 注意节流优化

猜你喜欢

转载自blog.csdn.net/weixin_44815800/article/details/130024395