Front-end Dom mouse click and drag

In the process of front-end time development, I encountered a demand for dragging the dom with the mouse. This demand is still very common. Share my thoughts with you.

There are two ways to solve this requirement. One is to use H5's native drag events ondragstart and ondragend, and the other is to monitor the onmousedown, onmousemove, and onmouseup events of the mouse.

ondragstart、ondragend详解

1. First confirm the dom that needs to be dragged, and add the attribute draggable to true, otherwise the ondragstart and ondragend and ondrag events will not take effect.

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

2. Add styles to the parent element and the drag element, mainly to position the position: relative and position: absolute

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

3. Get the position in the ondragStart event, the position of the dragged element in the parent, the relative position of the mouse, and get the mouse position in the ondragEnd event to calculate the relative position after the mouse has moved, and set a new position for the dragged element.

Note: The following code provides a way of writing drag and drop, it is not recommended to use it directly

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. Add styles to parent elements and drag-and-drop elements, mainly for positioning position: relative and position: absolute

  2. Get the initial position of the mouse in onmousedown, and create onmousemove monitoring and onmouseup monitoring

  3. In onmousemove, the position of the mouse is obtained, the position difference between the mouse and the initial position is calculated, and the boundary judgment is made and assigned to the position of the element.

  4. Cancel the monitoring of onmousemove in onmouseup

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>

Guess you like

Origin blog.csdn.net/glorydx/article/details/114282028