JSFiddle - React, Tailwind, and code Playground
by theodorejb
HTML
<a href="#" id="drag" draggable="true">Drag me</a>
<div id="drop" dropzone="copy">
<p>
Text node in child
<p>Text node in grandchild</p>
</p>
</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;
}
#drop * {pointer-events: none;}
JavaScript
/*
* This fiddle demonstrates a technique to prevent dragleave
* events from firing on parent elements when dragging over
* their children. Simply set the pointer-events CSS property
* to none on child elments of the drop target:
*
* #dropTarget * {pointer-events: none;}
*
* Note that *all* child nodes must be within a containing
* element for this to work in Firefox (no text nodes directly
* inside the drop target).
*
* Internet Explorer 8-10 do not support pointer events, so as
* a fallback event listeners are added to each child node,
* which add or remove an 'ignore-drag-leave' class from
* the drop target. This works because the dragenter event on
* child nodes is fired before the dragleave event on the parent.
*
* Open your console to view logged events as they are fired.
*
* This technique is tested and working on Chrome 29, Firefox
* 24, and Internet Explorer 8-11.
* More information: http://stackoverflow.com/a/18542687/1170489
*/
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 (!pointerEventsSupport() && 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...