React drag-and-drop sorting. It is used in the project, remember a pen. No use of REACT-DND, no use of REACT-BEAUTIFUL-DND, because the requirements are simple, so they have a.
The code is simple.
Defining a CSS, two animations
.drag-up {
-webkit-animation: dragup ease 0.2s 1;
animation: dragup ease 0.2s 1;
-webkit-animation-fill-mode: forwards;
animation-fill-mode: forwards;
background-color: red;
}
.drag-down {
-webkit-animation: dragdown ease 0.2s 1;
animation: dragdown ease 0.2s 1;
-webkit-animation-fill-mode: forwards;
animation-fill-mode: forwards;
background-color: green;
}
@-webkit-keyframes dragup {
from {
margin-top: 10px;
}
to {
margin-top: 60px;
}
}
@keyframes dragup {
from {
margin-top: 10px;
}
to {
margin-top: 60px;
}
}
@-webkit-keyframes dragdown {
from {
margin-bottom: 10px;
margin-top: 60px;
}
to {
margin-bottom: 60px;
margin-top: 10px;
}
}
@keyframes dragdown {
from {
margin-bottom: 10px;
margin-top: 60px;
}
to {
margin-bottom: 60px;
margin-top: 10px;
}
}
One is an upward-dragging animation, and the other is a downward-dragging style.
2. Write components
class List extends React.Component {
constructor (props) {
super (props);
this.state = {... props};
}
dragStart (e) {
this.dragged = e.currentTarget;
}
dragEnd (e) {
this.dragged.style.display = ‘block’;
e.target.classList.remove ("drag-up");
this.over.classList.remove ("drag-up");
e.target.classList.remove ("drag-down");
this.over.classList.remove ("drag-down");
var data = this.state.data;
var from = Number (this.dragged.dataset.id);
var to = Number (this.over.dataset.id);
data.splice (to, 0, data.splice (from, 1) [0]);
// set newIndex to judge direction of drag and drop
data = data.map ((doc, index) => {
doc.newIndex = index + 1;
return doc;
})
this.setState ((data: data));
}
dragOver (e) {
e.preventDefault ();
this.dragged.style.display = "none";
if (e.target.tagName! == "LI") {
return;
}
// Judge the newIndex of the current drag target and the passed target
const dgIndex = JSON.parse (this.dragged.dataset.item) .newIndex;
const taIndex = JSON.parse (e.target.dataset.item) .newIndex;
const animateName = dgIndex> taIndex? "drag-up": "drag-down";
if (this.over && e.target.dataset.item! == this.over.dataset.item) {
this.over.classList.remove ("drag-up", "drag-down");
}
if (! e.target.classList.contains (animateName)) {
e.target.classList.add (animateName);
this.over = e.target;
}
}
render () {
var listItems = this.state.data.map ((item, i) => {
return (
<li
data-id = (i)
key = (i)
style = {{height: "60px", border: "solid 1px #cccccc", margin: "10px 30%", borderRadius: "5px", backgroundColor: "green", color: "#ffffff"}}
draggable = ‘true’
onDragEnd = {this.dragEnd.bind (this)}
onDragStart = {this.dragStart.bind (this)}
data-item = {JSON.stringify (item)}
> {item.color} </ li>
)
});
return (
<ul onDragOver = {this.dragOver.bind (this)} className = "contain">
{listItems}
</ ul>
)
}
}
class App extends React.Component {
constructor (props) {
super (props);
this.state = {
data: [
{
newIndex: 1,
color: "red"
},
{
newIndex: 2,
color: "green"
},
{
newIndex: 3,
color: "blue"
},
{
newIndex: 4,
color: "yellow"
},
{
newIndex: 5,
color: "orange"
},
{
newIndex: 6,
color: "black"
}
]
}
}
render () {
return (
<div>
<List data = {this.state.data} />
</ div>
)
}
}
ReactDOM.render (
<App />,
document.getElementById (‘app‘),
);
Explain a few three ways
1.dragStart assigns the target value to this
2.dragOver the passed Li is assigned to this, and on the passing Li, add the corresponding class, to achieve animation effect. This compares the serial number to determine which direction is currently being dragged. And compare whether Li is the same or not, remove the animation effect.
3.dragEnd, remove the animation effect, and compare the data, setstate to the latest data.
Summarize the idea of a bit of dom manipulation.
Demo Address: Https://codepen.io/jhonyoung/pen/PeGpNL
Original.
React drag-and-drop sorting