JSFiddle - React, Tailwind, and code Playground

by Hans PUFAL

HTML

<div class="draggable"> 
     test1 
</div>
<br><br>
<div class="draggable" style="top: 5em; left: 5em;"> 
    <span class="dragHandle"> dragA </span>
     test2 
    <span class="dragHandle"> dragB </span>
</div>

CSS

.draggable {background-color: green; color: white;  width: 20em; height: 10em; }

JavaScript

(function () { //=========================================================== Draggable ===
  function startDrag (ev) { 
    var el = this,
        posX,
        posY;
        
    function mouseMove (ev) {
      el.style.left = (ev.clientX - posX) + 'px';
      el.style.top = (ev.clientY - posY) + 'px';
      ev.preventDefault ();
    }

    function mouseUp (ev) {
      document.removeEventListener ('mousemove', mouseMove, true);
      document.removeEventListener ('mouseup', mouseUp, true);
      ev.preventDefault ();
    }

    while (el && !el.classList.contains ('draggable'))
      el = el.parentNode;
 
    posX = ev.clientX - (window.getComputedStyle (el).left.match (/^(\d+)/) || [0,0])[1],
    posY = ev.clientY - (window.getComputedStyle (el).top.match (/^(\d+)/) || [0,0])[1];
      
    document.addEventListener ('mousemove', mouseMove, true); 
    document.addEventListener ('mouseup', mouseUp, true); 
    ev.preventDefault ();
  };

  [].forEach.call (document.querySelectorAll ('.draggable'), function (d) {
    var handles = [].slice.call (d.querySelectorAll ('.dragHandle'));
    d.style.position = 'absolute';
    !handles.length && (handles = [d]);
    handles.forEach (function (h) {
      h.addEventListener ('mousedown', startDrag, false);
      h.style.cursor = 'pointer';
    });
  });  
}) ();