Using the new feature of HTML5 to drag and drop to exchange table cell elements
What's new in HTML5: drag and drop
Drag and drop
Drag and Drop is a very common feature. It means you grab something and drag it into different positions.
Drag and drop is part of the HTML5 standard: any element can be dragged and dropped.
Browser support
The numbers in the table indicate the first browser version that fully supports drag and drop.
HTML drag and drop instance
The following is a simple example of drag and drop:
example
<!DOCTYPE HTML> <html> <head> <script> function allowDrop(ev) { ev.preventDefault(); } function drag(ev) { ev.dataTransfer.setData("text", ev.target.id); } function drop(ev) { ev.preventDefault(); var data = ev.dataTransfer.getData("text"); ev.target.appendChild(document.getElementById(data)); } </script> </head> <body> <div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div> <img id="drag1" src="img_logo.gif" draggable="true" ondragstart="drag(event)" width="336" height="69"> </body> </html>
Example URL: W3School TIY Editor
Drag and drop event details
-
Make elements drag and drop
First, to make an element drag and drop, set its draggable attribute to true:
<img draggable="true">
-
Set the contents of drag and drop - ondragstart and setData()
Then, specify what happens when the element is dragged.
In the above example, the ondragstart attribute calls a drag(event) function to specify what data to drag.
The dataTransfer.setData() method sets the data type and value of the dragged data:
function drag(ev) { ev.dataTransfer.setData("text", ev.target.id); }
In this case, the data type is "text" and the value is the id ("drag1") of the draggable element.
-
Set where to drag - ondragover
The ondragover event specifies where the dragged data can be placed.
By default, data / elements cannot be placed in other elements. In order to implement drag and drop, we must prevent this default processing of elements.
This task is completed by the event.preventDefault() method of the ondragover event:
function allowDrop(ev) { ev.preventDefault(); }
-
Place - ondrop
When the dragged data is released, a drop event occurs.
In the above example, the ondrop attribute calls a function, drop(event):
function drop(ev) { ev.preventDefault(); var data = ev.dataTransfer.getData("text"); ev.target.appendChild(document.getElementById(data)); }
Code interpretation:
-
Call preventDefault() to block the browser's default handling of data (the default behavior of drop events is to open as links)
-
Get the dragged data through the dataTransfer.getData() method. This method will return any data set to the same type in the setData() method
-
The dragged data is the id ("drag1") of the dragged element
-
Append the dragged element to the drop element
-
Project practical application
<table style="table-layout: fixed; line-height: 45px; font-size: 16px;" width="100%" border="1" cellpadding="4" cellspacing="0"> <tr style="background-color: rgb(132 188 247); color: rgb(255, 255, 255); text-align: center;"> <th>time slot</th> <th>Monday</th> <th>Tuesday</th> <th>Wednesday</th> <th>Thursday</th> <th>Friday</th> <th>Saturday</th> <th>Sunday</th> </tr> <tr style="text-align: center;"> <td>time slot</td> <td>......</td> <!-- The unimportant part has been omitted. It mainly realizes the drag and drop exchange of the following two cells --> <td> <div @drop="drop($event)" @dragover="allowDrop($event)" draggable="true" @dragstart="drag($event)" :id="test1.saturday.id"> {{test1.saturday.user}} </div> </td> <td> <div @drop="drop($event)" @dragover="allowDrop($event)" draggable="true" @dragstart="drag($event)" :id="test1.sunday.id"> {{test1.sunday.user}} </div> </td> </tr> </table>
// Drag and drop to exchange elements in cells function allowDrop(ev: any) { ev.preventDefault(); } // Triggered when dragging function drag(ev: any) { ev.dataTransfer.setData("id", ev.target.id); ev.target.style.border = "1px solid yellow"; ev.target.style.cursor = "pointer"; } // Trigger after lowering function drop(ev: any) { ev.preventDefault(); var data = ev.dataTransfer.getData("id"); swapElements(document.getElementById(data), ev.currentTarget); ev.target.style.border = "1px solid yellow"; ev.target.style.cursor = "pointer"; // Send exchange request axios.post('/apply/manager/arrange', { "method": "exchange", "shiftFirstId": data, "shiftSecondId": ev.target.id, }).then((res: any)=>{ if (res.code === 200) { message.success(res.msg); } else { message.error(res.msg); } }) } // Exchange element function swapElements(a: any, b: any) { // Swap two dom elements if (a == b) return; //Record parent element var bp = b.parentNode; var ap = a.parentNode; //Record the next sibling element var an = a.nextElementSibling; var bn = b.nextElementSibling; //If the reference is an adjacent element, adjust the position directly if (an == b) return bp.insertBefore(b, a); if (bn == a) return ap.insertBefore(a, b); if (a.contains(b)) { //If a contains b return ap.insertBefore(b, a), bp.insertBefore(a, bn); } else { return bp.insertBefore(a, b), ap.insertBefore(b, an); } }
Pit record
- Because the drag and drop exchange of two elements is required, both elements should set draggable to true and bind ondrop, ondragstart and ondragover events.
- In the drop method, ev.target.appendChild(document.getElementById(data)) cannot be simply used. If this method is actually used to append the content of element 1 to the dom of element 2, the exchange effect cannot be achieved.
- ev.target.replaceChild(document.getElementById(data), ev.target.firstChild) cannot be used for interchange, and bug s will occur.