JSFiddle - React, Tailwind, and code Playground
HTML
<div class="container">
<div class="dropper">
<div class="draggable">#1</div>
<div class="draggable">#2</div>
</div>
<div class="dropper">
<div class="draggable">#3</div>
<div class="draggable">#4</div>
</div>
</div>
CSS
.container {
max-height: 400px;
overflow: scroll;
}
.dropper {
margin: 50px 10px 10px 50px;
width: 400px;
height: 250px;
background-color: #555;
border: 1px solid #111;
border-radius: 10px;
transition: all 200ms linear;
}
.draggable {
display: inline-block;
margin: 20px 10px 10px 20px;
padding-top: 20px;
width: 80px;
height: 60px;
color: #3d110f;
background-color: #822520;
border: 4px solid #3d110f;
text-align: center;
font-size: 2em;
cursor: move;
transition: all 200ms linear;
user-select: none;
}
JavaScript
(function() {
var dndHandler = {
draggedElement: null,
applyDragEvents: function(element) {
element.draggable = true;
var dndHandler = this;
element.addEventListener("dragstart", function(e) {
dndHandler.draggedElement = e.target;
e.dataTransfer.setData("text/plain", "");
});
},
applyDropEvents: function(dropper) {
dropper.addEventListener("dragover", function(e) {
e.preventDefault();
});
var dndHandler = this;
dropper.addEventListener("drop", function(e) {
var target = e.target,
draggedElement = dndHandler.draggedElement,
clonedElement = draggedElement.cloneNode(true);
while (target.className.indexOf("dropper") == -1) {
target = target.parentNode;
}
target.className = "dropper";
clonedElement = target.appendChild(clonedElement);
dndHandler.applyDragEvents(clonedElement);
draggedElement.parentNode.removeChild(draggedElement);
});
}
};
var elements = document.querySelectorAll(".draggable"),
elementsLen = elements.length;
for (var i = 0; i < elementsLen; i++) {
dndHandler.applyDragEvents(elements[i]);
}
var droppers = document.querySelectorAll(".dropper"),
droppersLen = droppers.length;
for (var i = 0; i < droppersLen; i++) {
dndHandler.applyDropEvents(droppers[i]);
}
})();