Mousemove mousedown, mouseup implement drag and drop

In everyday coding, it is possible to encounter objects being moved by the user’s mouse, as shown in the figure above. After checking relevant blogs. My idea is to get the distance the object should move by the difference between where the mouse is pressed and where it is moved.

  let lastPositionX,lastPositionY,nowPostionX,nowPostionY
  dragElement.onmousedown=function(){  
	lastPositionX = event.clentX ;
  	lastPositionY = event.clentY ;
    
  }
  dragElement.onmousemove=function(){
  
    nowPositionX = event.clentX ;
    nowPositionY = event.clentY ;
    // The horizontal distance the object should move
    let moveeX = nowPostionX - lastPostionX
    // The longitudinal distance the object should move
    let moveY = nowPostionY - lastPostionY
    /* After getting the distance the object should move we should set the object's position */
  }
  
Copy the code

Because the mouse is inside the object, but setting the object distance is to set the distance between the object’s edge and the edge of the window. We know that the relative position of the mouse in the object should always remain the same, because the relative distance is determined when onMouseDown, so after solving x and Y in the figure above, the relative position of the object can be determined every time the mouse moves.

	// Determine the relative distance when onmouseDown
   x = event.clientX - drag.offsetLeft;
   y = event.clientY - drag.offsetTop;
Copy the code

In this way, we don’t care where the object should be moving, but where it is relative to the mouse. So object should set object

drag.style.left = event.clientX - x
// if x = event.clientx-drag. OffsetLeftDrag. Style. left = drag. OffsetLeft + event.clientx (now) - event.clientx (last)Copy the code

Isn’t that what we want? Get the position of the drag element from the relative position event.clientx (now) – event.clientx (last). Another thing to note is that if the mouse moves too fast, it may run out of elements and interrupt movement, so you can’t register onMousemove and onMouseup on the drag, it should be on the entire HTML. In addition, registered events can be cleared after completion to save memory. Attach the complete HTML code:

<! DOCTYPEhtml>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body style="background-color: gray;">
		<div draggable="true" id="drag" style="background-color: pink; width: 200px; height: 200px; position: absolute;"></div>
	</body>
	<script type="text/javascript">
		var drag = document.getElementById('drag'); 
		drag.onmousedown = function(event) {
			var event = event || window.event; // Compatible with Internet Explorer
			var x = event.clientX - drag.offsetLeft;
			var y = event.clientY - drag.offsetTop;
			if (typeofdrag.setCapture ! = ='undefined') {
				drag.setCapture();
			}
			document.onmousemove = function(event) {
				event.preventDefault()
				var event = event || window.event;
				var moveX = event.clientX - x;
				var moveY = event.clientY - y;
				if (moveX < 0) {
					moveX = 0
				} else if (moveX > window.innerWidth - drag.offsetWidth) {
					moveX = window.innerWidth - drag.offsetWidth
				}
				if (moveY < 0) {
					moveY = 0
				} else if (moveY > window.innerHeight - drag.offsetHeight) {
					moveY = window.innerHeight - drag.offsetHeight
				}
				drag.style.left = moveX + 'px';
				drag.style.top = moveY + 'px'
			}
			document.onmouseup = function(event) {
				// Multiple clicks register multiple events causing memory leaks
				document.onmousemove = null;
				document.onmouseup = null;
				// Fix bugs in earlier versions of Ie
				if (typeofdrag.releaseCapture ! ='undefined') { drag.releaseCapture(); }}}</script>
</html>


Copy the code

In React, dragging and dragging elements requires retrieving dom elements, so we use react.CreateRef to create a hook to connect elements.

  dragElementRef = React.createRef('dragEle');
 	// use ref to drag
  const drag = this.dragElementRef.current
  // The following code is the same as the HTML code
  drag.onmousedown = function(event) {
			var event = event || window.event; // Compatible with Internet Explorer
			var x = event.clientX - drag.offsetLeft;
			var y = event.clientY - drag.offsetTop;
			if (typeofdrag.setCapture ! = ='undefined') {
				drag.setCapture();
			}
			document.onmousemove = function(event) {
				event.preventDefault()
				var event = event || window.event;
				var moveX = event.clientX - x;
				var moveY = event.clientY - y;
				if (moveX < 0) {
					moveX = 0
				} else if (moveX > window.innerWidth - drag.offsetWidth) {
					moveX = window.innerWidth - drag.offsetWidth
				}
				if (moveY < 0) {
					moveY = 0
				} else if (moveY > window.innerHeight - drag.offsetHeight) {
					moveY = window.innerHeight - drag.offsetHeight
				}
				drag.style.left = moveX + 'px';
				drag.style.top = moveY + 'px'
			}
			document.onmouseup = function(event) {
				// Multiple clicks register multiple events causing memory leaks
				document.onmousemove = null;
				document.onmouseup = null;
				// Fix bugs in earlier versions of Ie
				if (typeofdrag.releaseCapture ! ='undefined') { drag.releaseCapture(); }}}// Render function returns
  <div className={styles.xxx} ref={this.dragElementRef} draggable="true" >
Copy the code

Dragstart drag Dragend implements drag

Dragstart Drag Dragend is similar to Mouse’s in that it provides some apis for drag and drop. Drag and drop refers to the position that will be dropped after being dragged. When the mouse clicks on the element and it starts to move, it will trigger a dragStart event (mouseDown) and it will trigger a drag event over and over again (Mousemove) and when you release the mouse and cancel the drag it will trigger a dragend event (Mouseup)

When a dragged element is dragged onto a target element, the target element fires the following event, which is the target element’s event instead of the dragged element.

The event name is Dragenter Dragover Dragleave DROP

Dragging an element onto a target triggers the Dragenter event (analogous to mouseover)

PreventDefault () if in mousemove event preventDefault() will not listen to drag event of dragged element as it prevents drag default behavior.

When the drag element is in the target element, the dragover event is continually fired

Leaving the target element triggers the Dragleave event (analogous to mouseout)

If you drop an element into the target element (releasing the mouse in the target element), the drop event is triggered instead of the dragleave event

<div draggable="true" id="drag2" style="background-color: yellow; width: 200px; height: 200px; position: absolute; margin-left: 250px;"></div>
Copy the code
drag.ondragstart = function(event) {
			var e = event || window.event
			console.log('Start dragging');
		}
		drag.ondrag = function() {
			console.log('Dragging');
		}
		drag.ondragend = function() {
			console.log('End of drag')}const target = document.getElementById("drag2")
		target.ondragenter = function() {
			console.log('Enter target element')
		}
		target.ondragover = function(event) {
			var event = event || window.event;
			console.log('Drag and drop in target element');
			event.preventDefault()
		}
		target.ondragleave = function() {
			console.log('Drag and drop away from target element')
		}
		target.ondrop = function(event) {
			console.log('drag and drop');
			var e = event || window.event;

		}
Copy the code

The interaction of elements in the drag-and-drop process. When the drag-and-drop element encounters another element, the intermediate variable event. DataTransfer can be used to store verses and fetch data, just like localstorage. The difference between localStorage and Datatransfer is that localstorage exists on disk while datatransfer exists in memory, which is faster

e.dataTransfer.setData(‘text’,e.target.id); Similar to the localstorage. SetItem (‘ text ‘, e. arget. Id)

e.dataTransfer.getData(‘text’,e.target.id); Similar to the localstorage. The getItem (‘ text ‘, e. arget. Id)

The following example implements an element into another element, using the dataTransfer, adding two lines to the original code value.

<! DOCTYPEhtml>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body style="background-color: gray;">
		<div draggable="true" id="drag" style="background-color: pink; width: 200px; height: 200px; position: absolute;"></div>
		<div draggable="true" id="drag2" style="background-color: yellow; width: 200px; height: 200px; position: absolute; margin-left: 250px;"></div>
	</body>
	<script type="text/javascript">
		var drag = document.getElementById('drag');
		drag.ondragstart = function(event) {
			var e = event || window.event
			console.log('Start dragging');
			e.dataTransfer.setData('text',e.target.id); / / add
		}
		drag.ondrag = function() {
			console.log('Dragging');
		}
		drag.ondragend = function() {
			console.log('End of drag')}const target = document.getElementById("drag2")
		target.ondragenter = function() {
			console.log('Enter target element')
		}
		target.ondragover = function(event) {
			var event = event || window.event;
			console.log('Drag and drop in target element');
			event.preventDefault()
		}
		target.ondragleave = function() {
			console.log('Drag and drop away from target element')
		}
		target.ondrop = function(event) {
			console.log('drag and drop');
			var e = event || window.event;
			var data = e.dataTransfer.getData('text');
			e.target.appendChild(document.getElementById(data));/ / add
		}
	</script>
</html>

Copy the code

There are also some important apis in dataTransfer that dictate the behavior of drag elements.

dropEffect

The dropEffect property value is a string indicating which drop behavior the dragged element can perform

To use this property, you must set it in the Dragenter event handler

None cannot drag elements to this point (default value for all elements except text boxes)

Move Moves to the target

Copy Copies to the target

Link target opens the drag element (drag element must be a link and have a URL)

effectAllowed

The effectalhoward property value is also a string, indicating which dropEffect is allowed to drag elements

To use this property, you must set it in the dragst event handler

Uninitialized does not set any drag and drop behavior

None cannot be defined by any behavior

Copy Only the dropEffect value can be copy

Link Only the dropEffect value can be link

Move Only the dropEffect value can be move

CopyLink allows dropEffect values to be copy and link

CopyMove allows dropEffect values to be copy and move

LinkMove allows the dropEffect value to be link and move

All allows any dropEffect

Reference link: blog.csdn.net/weixin_4191…