前端Dom鼠标点击拖拽

前端时间开发的过程中,遇到一个鼠标拖拽dom的需求,这个需求还是十分常见的,与大家一起分享我的想法。

解决这个需求有两种思路,其中一种是通过H5原生的拖拽事件ondragstart、ondragend,另一种则是通过监听鼠标的onmousedown、onmousemove、onmouseup事件。

ondragstart、ondragend详解

1.首先确认需要被拖拽的dom,在上面加上属性draggable为true,否则ondragstart和ondragend和ondrag事件都无法生效。

<div draggable>
可拖拽元素
</div>

2.给父级元素和拖拽元素加样式,主要是为了定位postion:relative 和position:absolute

.parent {
    
    
position: relative,
width: 800px,
height: 800px
}
.dragDom {
    
    
position: absolute,
width: 30px,
height: 30px,
x: 10,
y: 10
}

3.在ondragStart事件中获取位置,拖拽元素在父级的位置,鼠标相对位置,在ondragEnd事件中获取鼠标位置,从而计算出鼠标移动后的相对位置,并给拖拽元素设置新的位置。

注意: 以下代码提供了拖拽的一种写法思路,不建议直接使用

const [startX, setStartX] = useState<number>(0); // 元素初始位置
const [startY, setStartY] = useState<number>(0); // 元素初始位置
let startMouseX = 0;
let startMouseY = 0;

<div className="parent "> 
<div style={
    
    {
    
    
	position: 'absolute',
    left: startX ,
   	top: startY,
}}  
onDragStart={
    
    (e) => {
    
    
	let e = event || window.event;
    startMouseX = e.clientX; //初始鼠标位置
    startMouseY = e.clientY; //初始鼠标位置
}} 
onDragEnd={
    
    
(e) => {
    
    
	const DisX = e.clientX - startMouseX; // 鼠标相对移动距离
	const DisY = e.clientY - startMouseY; // 鼠标相对移动距离
	let newX = startX + DisX; // 被拖拽元素的新位置
	let newY = startY + DisY; // 被拖拽元素的新位置
	
	const DomWidth = e.target.offsetWidth; // dom的宽度
	const DomHeight = e.target.offsetHeight; // dom的高度
	
	// 边界判断
	if(newX <= 0) {
    
    
		newX = 0
	}
	// 父级的盒子宽度为800
	if(newX >= (800 - DomWidth ) ) {
    
    
		newX = 800 - DomWidth
	}
	if(newY <= 0) {
    
    
		newY = 0
	}
	// 父级的盒子高度为800
	if(newY >= (800 - DomHeight )) {
    
    
		newY = 800 - DomHeight
	}
	setStartX(newX)
	setStartX(newY)
}}>
被拖拽的组件
</div>
</div>
onmousedown、onmousemove、onmouseup详解
  1. 给父级元素和拖拽元素加样式,主要是为了定位postion:relative 和position:absolute

  2. 在onmousedown中获取鼠标的初始位置,并创建onmousemove的监听和onmouseup的监听

  3. 在onmousemove中,获取鼠标的位置,计算出鼠标与初始位置的位置差,并作出边界判断,赋值给元素的位置,

  4. 在onmouseup中取消掉onmousemove的监听

const [startX, setStartX] = useState<number>(0); // 元素初始位置
const [startY, setStartY] = useState<number>(0); // 元素初始位置
let startMouseX = 0;
let startMouseY = 0;

<div className="parent "> 
	<div style={
    
    {
    
    
	position: 'absolute',
    left: startX ,
   	top: startY,
}}
onMouseDown={
    
    (e) => {
    
    
 let e = event || window.event;
  const dom = e.target;
   /** 被点击元素本身的宽和高 */
    const domWidth = dom.offsetWidth;
    const domHeight = dom.offsetHeight;
    /** 被点击元素的边界值 */
    const overRigth = 800 - domWidth;
    const overBottom = 800 - domHeight;
	
	const handler = (event: any) => {
    
    
      const nowX = event.clientX;
      const nowY = event.clientY;

      const disX = nowX - startMouseX ;
      const disY = nowY - startMouseY;
      
      let targetX = initX + disX;
      let targetY = initY + disY;
		
		  if (targetX <= 0) {
    
    
            targetX = 0;
          }
          if (targetY <= 0) {
    
    
            targetY = 0;
          }

          if (targetX >= overRigth) {
    
    
            targetX = overRigth;
          }

          if (targetY >= overBottom) {
    
    
            targetY = overBottom;
          }
		setStartX(targetX )
      	setStartY(targetY )
    };
	
	// 请将mousemove和mouseup放到document上,否则鼠标移动太快可能会脱节,也就是被拖拽的dom跟不上鼠标的速度。哈哈
	document.addEventListener('mousemove', handler, false);
    document.addEventListener(
      'mouseup',
      () => {
    
    
        document.removeEventListener('mousemove', handler);
      },
      false,
    );
}}
> 被拖拽组件 </div>
</div>

猜你喜欢

转载自blog.csdn.net/glorydx/article/details/114282028