JSFiddle - React, Tailwind, and code Playground

by theodorejb

HTML

<a href="javascript:void(0)" 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).
 *
 * 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 11. If you need to support previous
 * versions of IE, use the technique at
 * http://jsfiddle.net/theodorejb/j2fDt/8/.
 * More information: http://stackoverflow.com/a/18542687/1170489
 */

var drag = document.getElementById('drag');
var drop = document.getElementById('drop');

drag.addEventListener('dragstart', startDrag, false);
drag.addEventListener('dragend', endDrag, false);

drop.addEventListener('dragenter', handleDragEnter, false);
drop.addEventListener('dragover', handleDragOver, false);
drop.addEventListener('dragleave', handleDragLeave, false);
drop.addEventListener('drop', handleDrop, false);

function startDrag(e) {
    console.log('Dragging button');
    e.dataTransfer.setData("Text", "my data");
    e.dataTransfer.dropEffect = "copy";
    drop.classList.add('dragging');
}

function endDrag(e) {
    console.log('Finished dragging button');
    drop.classList.remove('dragging');
}

function handleDragEnter(e) {
    e.preventDefault();
    console.log('Entering parent');
    this.classList.add('over');
}

function handleDragOver(e) {
    e.preventDefault();
}

function handleDragLeave(e) {
    this.classList.remove('over');
    console.log('Leaving parent');
}

function handleDrop(e) {
    e.preventDefault(); // prevent navigation when dropping links
    var data = e.dataTransfer.getData("Text");
    console.log('Button dropped with data: ' + data);
   ...