First, drag and drop

Drag and drop is a common feature where you grab an object and drag it to another location. So there are two actions: drag and drop.

In HTML5, drag and drop is part of the standard, and any element can be dragged and dropped. Its property is draggable:true, which, when true, is dragable

Second, the data

The DataTransfer object is used to hold data during drag-and-drop. The data can be one or more items, and the data items can be one or more data types.

This is used to get the list of files being dragged when we implement drag upload.

Three, events,

Since drag and drop is divided into drag and drop parts, we can divide the target into drag elements and target elements to be placed.

The name of the event time target
ondragstart Triggered when drag elements start to be dragged Drag and drop elements
ondragend Trigger when drag is complete Drag and drop elements
ondragenter Triggered when an element is dragged into the target element The target element
ondragover Triggered when a drag element is moved on the target element The target element
ondragleave Triggered when a drag element leaves the target element without dropping it The target element
ondrop Drag elements over target elements while mouse release triggers The target element

Note: The onDragover event is emitted every 350 milliseconds as you drag an element.

In the onDragover event, be sure to implement methods that prevent the default event from executing: The event.preventDefault () method, otherwise the onDROP Event will not be triggered. For file drags, the default action is to display image information or download the file, so prevent the default action to perform our upload in onDrop.

4. Problems encountered

In the process of do drag and drop to upload the file, the file into the target vessel, the need to display mask layer for prompt upload “, “release the mouse, target is container div, ondragover of target container, ondragenter, ondrop event listeners, there will be a mask layer stroboscopic problem.

Problem a:

At that time, it was in the project, so I wanted to write a small Demo to demonstrate. First, I only wrote a target container and a mask layer, and tried to drag the file, only to find that stroboscope still appeared. It is normal to browse the online tests on drag events, because most of them are tested by changing CSS properties, not by the mask layer, which is controlled by the display property, so the dragenter is triggered by dragging the target container, but the mask layer shows at this time, Then the dragleave will be triggered, so the cycle will cause the phenomenon of stroboscopic, which is actually the result of the interaction between drag operation and mask concealment.

\

Solution: Since the mask layer is a hint, you can lower it to ensure that when you drag files, they are in the target container, eliminating the interaction effect.

Problem two:

Drag file from bottom to top with mask layer (in target container) – no mask layer (in child container) – No mask layer (in target container) – No mask layer (in target container)

On entering a container, the previous container exits, and on exiting the destination container for the last time, there is only the exit event. To solve this problem, you can save the last element entered, and only the last element entered will exit the target container

Five, the summary

The onDrop event can only be triggered if the default event is prevented from executing in the onDragover event

2. Pay attention to the level of the target container when dragging, so as not to be affected

3. When there are sub-containers, it is necessary to determine when the target container is really exited. You can compare the last container with the target of dragleave by saving it.


Six, supplement

About mask layer implementation:

1. Add a div (above)

2, through pseudo class to achieve:

<! <div id=" onDragEnter =" onDragenter (event)" ondragover=" ondragover (event)" ondragleave="onDragLeave(event)" ondrop="onDrop(event)"> <div id="drag_child"></div> </div> <! <style>. Drag_zone :after{content: attr(data-attr); width: 500px; height: 400px; background-color: deepskyblue; Opacity: 0.1; position: absolute; display: block; z-index: -1; top: 100px; left: 109px; text-align: center; } </style> <! <script> var lastenter = null; function onDragEnter(ev){ lastenter = ev.target; document.getElementById('drag_zone').setAttribute('class','drag_zone'); Console. log('onDragEnter, entry element is ',ev.target.id); } function onDragOver(ev){ ev.preventDefault(); } function onDragLeave(ev){ if(lastenter === ev.target){ ev.preventDefault(); ev.stopPropagation(); Document. The getElementById (' drag_zone). RemoveAttribute (' class ') console. The log (' onDragLeave, Function onDrop(ev){ev.preventdefault (); console.log('onDrop',ev.target.id); document.getElementById('drag_zone').removeAttribute('class') console.log(ev.dataTransfer); } </script>Copy the code

On hierarchical solutions:

Use the CSS attribute pointer-Events, set to None, to indicate that the element will never be the target of mouse events that “Pierce” it.

#mask{
      width: 500px;
      height: 400px;
      background-color: deepskyblue;
      opacity: 0.1;
      position: absolute;
      display: none;
      top: 170px;
      left: 109px;
      pointer-events: none;
    }
Copy the code