title: Swap places on moving on element like in Windows taskbar (pure JavaScript)
body: <p>I wrote this code to make any element with class <code>draggable</code> draggable.</p>
  <p><div class="snippet" data-lang="js" data-hide="true" data-console="true" data-babel="false">
  <div class="snippet-code snippet-currently-hidden">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>const d = document.getElementsByClassName("draggable");
  
  for (let i = 0; i &lt; d.length; i++) {
    d[i].style.position = "relative";
  }
  
  function filter(e) {
    let target = e.target;
  
    if (!target.classList.contains("draggable")) {
      return;
    }
  
    target.moving = true;
    
    e.clientX ?
    (target.oldX = e.clientX,
    target.oldY = e.clientY) :
    (target.oldX = e.touches[0].clientX,
    target.oldY = e.touches[0].clientY)
  
    target.oldLeft = window.getComputedStyle(target).getPropertyValue('left').split('px')[0] * 1;
    target.oldTop = window.getComputedStyle(target).getPropertyValue('top').split('px')[0] * 1;
  
    document.onmousemove = dr;
    document.addEventListener('touchmove', dr, {passive: false})
  
    function dr(event) {
      event.preventDefault();
  
      if (!target.moving) {
        return;
      }
  
      event.clientX ?
      (target.distX = event.clientX - target.oldX,
      target.distY = event.clientY - target.oldY) :
      (target.distX = event.touches[0].clientX - target.oldX,
      target.distY = event.touches[0].clientY - target.oldY)
  
      target.style.left = target.oldLeft + target.distX + "px";
      target.style.top = target.oldTop + target.distY + "px";
    }
  
    function endDrag() {
      target.moving = false;
    }
    target.onmouseup = endDrag;
    target.ontouchend = endDrag;
  }
  document.onmousedown = filter;
  document.ontouchstart = filter;</code></pre>
  <pre class="snippet-code-css lang-css prettyprint-override"><code>div {
    width: 100px;
    height: 100px;
    background: red;
  }</code></pre>
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;div class="draggable"&gt;&lt;/div&gt;</code></pre>
  </div>
  </div>
  </p>
  <p><strong>tl;dr- I want to make a Windows taskbar thing where elements can be moved and the other elements move to the right or left based on where the dragged element is approaching it.</strong></p>
  <p>I want the <em>draggable</em> elements to snap to the grid similar to what happens when you drag an icon on the Windows taskbar or a tab on another tab in your browser.</p>
  <p>Following is my attempt. I removed movement along the verticle axis and touch support to make the code more readable. The snapping is working fine but the element being hovered is not moving to the other space.</p>
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>const d = document.getElementsByClassName("draggable");
  
  let grid = 50;
  
  for (let i = 0; i &lt; d.length; i++) {
    d[i].style.position = "relative";
    d[i].onmousedown = filter;
  }
  
  function filter(e) {
    let target = e.target;
  
    target.moving = true;
    target.oldX = e.clientX;
  
    target.oldLeft = window.getComputedStyle(target).getPropertyValue('left').split('px')[0] * 1;
  
    document.onmousemove = dr;
  
    function dr(event) {
      event.preventDefault();
  
      if (!target.moving) {
        return;
      }
  
      target.distX = event.clientX - target.oldX;
      
      target.style.left = target.oldLeft + Math.round(target.distX / grid) * grid + 'px'
    }
  
    function endDrag() {
      target.moving = false;
    }
    document.onmouseup = endDrag;
  }</code></pre>
  <pre class="snippet-code-css lang-css prettyprint-override"><code>.parent {
    width: 100%;
    height: 100%;
    background: lime;
    display: flex;
    align-items: center;
  }
  
  .child {
    width: 50px;
    height: 50px;
    position: relative;
  }
  
  .one {
    background: red;
  }
  
  .two {
    background: blue;
  }</code></pre>
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;div class="parent"&gt;
    &lt;div class="child one draggable"&gt;&lt;/div&gt;
    &lt;div class="child two draggable"&gt;&lt;/div&gt;
  &lt;/div&gt;</code></pre>
  </div>
  </div>
  </p>
  <p>Further, I think checking for when the mouse has crossed half of the width of a <code>div</code>, while an element is being dragged, the <code>div</code> should move either one unit left or right depending whether the element is left or right to the element being dragged. The checking part is no trouble. We can just compare the magnitudes of the elements' <code>offsetLeft</code>. But <strong>how do I make the element move?</strong></p>
  <p>Please try to answer in vanilla javascript.</p>
  <sub>
  Edits: 1. Updated code 2. Updated title 3. Updated tl;dr and changed title 3.Added more tags
  </sub>