JSFiddle - React, Tailwind, and code Playground
by theodorejb
HTML
<a href="#" id="drag" draggable="true">Drag me</a>
<div id="drop" dropzone="copy">
Text node in parent
<p>
Text node in child
<p>Text node in grandchild</p>
</p>
Text node in parent
</div>
CSS
body {
padding: 5px;
font-family: Arial, sans-serif;
}
#drag {
display: inline-block;
text-decoration: none;
border: 1px solid gray;
color: #111;
background-color: #dfdfdf;
padding: 8px 14px;
}
#drop {
margin-top: 10px;
background-color: #e3e3e3;
padding: 8px;
}
#drop.over {
background-color: #d1d1d1;
}
#drop.dragging {
padding: 18px;
border: 1px dashed gray;
}
#drop p {
margin: 10px 0;
}
JavaScript
/*
* While it isn't possible to prevent the dragleave event from
* firing on parent elements when dragging over their children
* in IE 8-10, it is possible to ignore it. To do this, add
* dragenter and dragleave event listeners to each child node
* which will add or remove an 'ignore-drag-leave' class from
* their parent. This works because the dragenter event on
* child nodes is fired before the dragleave event on the parent.
*
* This technique is tested and working in Chrome, Firefox, and
* IE8+. If you don't need to support versions of IE prior to
* IE11, use this simpler solution: http://jsfiddle.net/theodorejb/4ZGvv/.
*/
var drag = document.getElementById('drag');
var drop = document.getElementById('drop');
addEvent(drag, 'dragstart', startDrag);
addEvent(drag, 'dragend', endDrag);
addEvent(drop, 'dragenter', handleDragEnter);
addEvent(drop, 'dragleave', handleDragLeave);
addEvent(drop, 'dragover', handleDragOver);
addEvent(drop, 'drop', handleDrop);
if (drop.hasChildNodes) {
var children = drop.childNodes;
for (var i = 0; i < children.length; i++) {
var node = children[i];
addEvent(node, 'dragenter', handleChildDragEnter);
addEvent(node, 'dragleave', handleChildDragLeave);
console.log('Added event listeners to child node #' + i);
}
}
function startDrag(e) {
console.log('Dragging button');
e.dataTransfer.setData("Text", "my data");
e.dataTransfer.dropEffect = "copy";
$(drop).addClass('dragging');
}
function endDrag(e) {
console.log('Finished dragging button');
$(drop).removeClass('dragging');
}
function handleDragEnter(e) {
stopEvent(e);
console.log('Entering parent');
$(drop).addClass('over');
}
function handleDragOver(e) {
stopEvent(e);
}
function handleDragLeave(e) {
if (!hasIgnoreClass(drop)) {
$(drop).removeClass('over');
console.log('Leaving parent');
}
}
function handleDrop(e) {
stopEvent(e); // prevent navigation...