This is the 17th day of my participation in the August Challenge

First, foundation drag

  • Requirement: box dragObj in the page, we need it to have drag function;

    1. Click on the box without releasing the left mouse button
    2. Hold down the left mouse button and do not release the mouse. When the mouse moves, the box should follow the box.
    3. When I drag to the destination (where I want to stop dragging) and release the left mouse button, the box will stop where I released the mouse button;
    4. When I release the mouse, no matter how MUCH I move the mouse, the box can’t move
  • Implementation idea: We analyzed the drag-and-drop phase of requirements and found that movement is divided into three phases

    1. [Fixed] Give the box the ability to be dragged when the mouse is pressed down.
    2. Drag is mouse movement, box follow, in the case of mousemove, mouse follow;
    3. Release the left mouse button to move the box’s ability to be dragged

In summary, bind the mousemove event to the element when the mouse is down, that is, when the mousedown event is triggered. Implement mouse following in mousemove events. Remove the ability to be dragged in the mouseup event function (remove the Mousemove event while mouseup).

  • The HTML code
<! DOCTYPEhtml>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <title>Title</title>
   <style>
      * {
         margin: 0;
         padding: 0;
      }
      .dragObj {
         position: absolute;
         width: 200px;
         height: 200px;
         background: red;
      }
      .box {
         width: 300px;
         height: 300px;
         background: #00b38a;
      }
   </style>
</head>
<body>
<div class="dragObj" id="dragObj" style="left: 100px; top: 100px"></div>
<div class="box" id="box"></div>

<script src="Js /6- Ready-to-publish.js"></script>
</body>
</html>
Copy the code
  • JS
let dragObj = document.getElementById('dragObj');

dragObj.onmousedown = dragStart; // Monitor the box's mouse-down event, and give the box the ability to be dragged in the event function;
dragObj.onmouseup = dragEnd; // Mouse lift ends drag
function dragStart(e) {
   // Start dragging
   // 1. Record the initial position of the box and the position where the mouse is pressed
   this.startL = parseFloat(this.style.left);
   this.startT = parseFloat(this.style.top);

   // 2. Record the mouse position when the mouse is pressed down
   this.startX = e.pageX;
   this.startY = e.pageY;

   // 3. Give elements the ability to be dragged
   dragObj.onmousemove = dragMove;

}

function dragMove(e) {
   // Drag: during the drag process, continuously calculate the distance between the current position of the mouse and the position of the mouse down, and then add the initial position of the box, which is the position of the box

   // 1. Calculate the distance moved by the current mouse position relative to the mouse down
   let moveX = e.pageX - this.startX;
   let moveY = e.pageY - this.startY;

   // 2. Calculate where the box should appear

   let curL = this.startL + moveX;
   let curT = this.startT + moveY;

   // 3. Set the left and top of the box to the value it should appear
   this.style.left = `${curL}px`;
   this.style.top = `${curT}px`;

}

function dragEnd() {
   dragObj.onmousemove = null;
}
Copy the code

Two, solve the loss of the mouse

2.1 Causes of mouse Loss:

When the mouse moves, it takes time for the browser to calculate where the box should appear. If you move the mouse again during the calculation period, because the position of the box has not been calculated in the last mousemove, the box cannot go to the right position. At this time, the mouse goes to a new position, so the box cannot keep up, so the mouse loses the box. When you lose an element, even if the mouse moves over it, but not over it, you can’t trigger the element’s onMousemove event, so the element no longer follows the mouse. Lifting the left mouse button after missing elements does not trigger the box’s mouseup event, so the box’s ability to follow the mouse is not removed, which causes the box to move when the mouse is over the box again.

2.2 Solution:

  1. SetCapture () and releaseCapture() when the drag is complete
  2. We bind the element’s Mousemove and Mouseup events to the Document because we can’t move the mouse out of the browser page. (Use the idea of event delegation to solve the problem)

let dragObj = document.getElementById('dragObj');

dragObj.onmousedown = dragStart;
dragObj.onmouseup = dragEnd;
function dragStart(e) {
   // this.setCapture();
   this.startX = e.pageX;
   this.startY = e.pageY;

   this.startL = parseFloat(this.style.left);
   this.startT = parseFloat(this.style.top);


   document.onmousemove = dragMove.bind(this);
}

function dragMove(e) {
   let moveX = e.pageX - this.startX;
   let moveY = e.pageY - this.startY;

   let curL = this.startL + moveX;
   let curT = this.startT + moveY;

   this.style.left = curL + 'px';
   this.style.top = curT + 'px';
}

function dragEnd(e) {
   // this.releaseCapture()
   document.onmousemove = null;
}
Copy the code

Three, native drag and drop

HTML5 supports drag and drop natively, but you need to set draggable = true for the element being dragged;

  • HTML code:
<! DOCTYPEhtml>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <title>Title</title>
   <style>
      #litBox {
         position: absolute;
         width: 100px;
         height: 100px;
         background: red;
      }
      #bigBox {
         width: 300px;
         height: 300px;
         border: 1px solid # 000;
         margin: 50px auto;
      }
      #fileBox {
         margin: 30px auto;
         width: 300px;
         height: 300px;
         border: 3px dashed #00b38a;
         border-radius: 5px;
         text-align: center;
      }
      #fileBox:before {
         content: '+';
         font-size: 200px;
         text-align: center;
         line-height: 250px;
         color: # 333333;
      }
   </style>
</head>
<body>
<div class="fileBox" id="fileBox"></div>
<div id="litBox" draggable="true"></div>
<div id="bigBox"></div>



<script src="Js / 5 - the dataTransfer object. Js." "></script>
</body>
</html>
Copy the code

3.1 Native drag and drop implementation is also based on native drag and drop events

 let litBox = document.getElementById('litBox');
  let bigBox = document.getElementById('bigBox');
Copy the code

3.2 ondragstart

  • Began to drag and drop

  • It is triggered by pressing and moving the mouse

  litBox.ondragstart = function (e) {
   console.log('start');
   e.dataTransfer.setData('Text'.this.id);
  };

Copy the code

3.3 ondrag

  • Trigger during the drag process
 litBox.ondrag = function () {
   // The drag process is triggered
   console.log('dragging')};Copy the code

3.4 ondragend

  • Drag ends trigger
  litBox.ondragend = function () {
   console.log('end')};Copy the code
  • All three are relative to the element being dragged;

  • The following events are relative to placed elements:

3.5 ondragover

  • BigBox’s onDragover event is triggered when a dragged element passes through it
  bigBox.ondragover = function (e) {
   // bigBox's onDragover event is triggered when a dragged element passes through it
   console.log('over');
   this.style.backgroundColor = 'blue';
   e.preventDefault();
  };
Copy the code

3.6 ondragleave

  • Emitted when the dragged element passes out of the bigBox

  bigBox.ondragleave = function () {
   // Emitted when the dragged element passes out of the bigBox
   this.style.backgroundColor = ' ';
   console.log('leave')};Copy the code

ondrop

  • Triggered when the dragged element releases the mouse over the bigBox
  bigBox.ondrop = function (e) {
   Emitted when the dragged element releases the mouse on the bigBox
   console.log('drop');
   console.log(e.dataTransfer.getData('Text'))
   let id = e.dataTransfer.getData('Text');
   bigBox.appendChild(document.getElementById(id))
  };

Copy the code

DataTransfer object

In the native drag-and-drop event, you can customize the storage data; Among the drag-and-drop event objects is a dataTransfer object, on which data can be stored or read by custom;

4.1 storage:

  • dataTransfer.setData(‘key’, ‘value’)

4.2 access to:

  • dataTransfer.getData(‘key’)
let litBox = document.getElementById('litBox');
let bigBox = document.getElementById('bigBox');

litBox.ondragstart = function (e) {
   // The element ID needs to be set during drag
   e.dataTransfer.setData('id'.this.id);
};

bigBox.ondragover = function (e) {
   // Block the default behavior in drageover, otherwise the ondraop event cannot be fired
   e.preventDefault();
};

bigBox.ondrop = function (e) {
   let id = e.dataTransfer.getData('id'); // Get the id of the dragged element from getData of the e.datatransfer object
   console.log(id)
};

// In addition, if you are dragging files to the placed target element, the information about these files is stored in datatransfer. files;
let fileBox = document.getElementById('fileBox');
fileBox.ondragover = function (e) {
   e.preventDefault();
};
fileBox.ondrop = function (e) {
   console.log(e.dataTransfer.files);
   // name: file name with extension name
   // size: indicates the file size
   // type: 'text/plain'
   e.preventDefault();
};

Copy the code

Native drag and drop examples

Native drag and drop implementations are also based on native drag and drop events

  • Drag the small box litBox from the page to the large box
  1. You need to set the element ID when you drag it;
  2. Block the default behavior in drageover, otherwise the ondraop event cannot be fired;
  3. Get the id of the dragged element through getData of the E.datatransfer object;
  4. Modify DOM node relationship;


let litBox = document.getElementById('litBox');
let bigBox = document.getElementById('bigBox');

litBox.ondragstart = function (e) {

   e.dataTransfer.setData('id'.this.id);
};

bigBox.ondragover = function (e) {
   
   e.preventDefault();
};
bigBox.ondrop = function (e) {
   let id = e.dataTransfer.getData('id'); // 

   let ele = document.getElementById(id);
   this.appendChild(ele);
   e.preventDefault();
};
Copy the code