Search code examples
javascripthtmlcssdrag-and-drop

Can't the css of the dragged element be modified in the vanilla javascript drag event?


I want the dragged element not to be blurred.

enter image description here

When dragged as in the photo above, the element is blurred. However, I want to keep the element even when dragged like the picture below.

enter image description here

How can I implement it using only Vanilla Javascript + css without using JQuery, any other library?

const draggables = document.querySelectorAll(".draggable");
const containers = document.querySelectorAll(".container");

containers.forEach((container) => {
  container.addEventListener("dragover", (e) => {
    e.stopPropagation();
    e.preventDefault();

    const afterElement = getDragAfterElement(container, e.clientY);
    const draggable = document.querySelector(".dragging");

    if (afterElement == null) {
      container.appendChild(draggable);
    } else {
      container.insertBefore(draggable, afterElement);
    }
  });

  container.addEventListener("dragstart", (e) => {
    const id = e.target.id;
    const box = document.getElementById(id);

    box.classList.add("dragging");
  });

  container.addEventListener("dragend", (e) => {
    const id = e.target.id;
    const box = document.getElementById(id);

    box.classList.remove("dragging");
  });
});

function getDragAfterElement(container, y) {
  const draggableElements = [
    ...container.querySelectorAll(".draggable:not(.dragging)"),
  ];

  return draggableElements.reduce(
    (closest, child) => {
      const box = child.getBoundingClientRect();
      const offset = y - box.top - box.height / 2;
      // console.log(offset);

      if (offset < 0 && offset > closest.offset) {
        return {
          offset: offset,
          element: child,
        };
      }
      return closest;
    },
    { offset: Number.NEGATIVE_INFINITY }
  ).element;
}
<body>
  <div class="container">
    <p id="box1" class="draggable" draggable="true">1</p>
    <p id="box2" class="draggable" draggable="true">2</p>
  </div>

  <div class="container">
    <p id="box3" class="draggable" draggable="true">3</p>
    <p id="box4" class="draggable" draggable="true">4</p>
  </div>

  <script src="./script.js"></script>
</body>
body {
  margin: 0px;
}

.container {
  background-color: #333;
  padding: 1rem;
  margin-top: 1rem;
}

.draggable {
  padding: 1rem;
  background-color: #fff;
  border: 1px solid black;
  cursor: move;
}

.draggable.dragging {
  opacity: 0.5;
}

The code above is the code I implemented. Currently this code is being dragged, but the dragged element is blurred.

Any ideas would be appreciated.


Solution

  • Remove this code:

    .draggable.dragging {
      opacity: 0.5;
    }
    

    Or modify it as below:

    .draggable.dragging {
      opacity: 1;
    }
    

    It will solve your issue

    const draggables = document.querySelectorAll(".draggable");
    const containers = document.querySelectorAll(".container");
    
    containers.forEach((container) => {
      container.addEventListener("dragover", (e) => {
        e.stopPropagation();
        e.preventDefault();
    
        const afterElement = getDragAfterElement(container, e.clientY);
        const draggable = document.querySelector(".dragging");
    
        if (afterElement == null) {
          container.appendChild(draggable);
        } else {
          container.insertBefore(draggable, afterElement);
        }
      });
    
      container.addEventListener("dragstart", (e) => {
        const id = e.target.id;
        const box = document.getElementById(id);
    
        box.classList.add("dragging");
      });
    
      container.addEventListener("dragend", (e) => {
        const id = e.target.id;
        const box = document.getElementById(id);
    
        box.classList.remove("dragging");
      });
    });
    
    function getDragAfterElement(container, y) {
      const draggableElements = [
        ...container.querySelectorAll(".draggable:not(.dragging)"),
      ];
    
      return draggableElements.reduce(
        (closest, child) => {
          const box = child.getBoundingClientRect();
          const offset = y - box.top - box.height / 2;
          // console.log(offset);
    
          if (offset < 0 && offset > closest.offset) {
            return {
              offset: offset,
              element: child,
            };
          }
          return closest;
        }, {
          offset: Number.NEGATIVE_INFINITY
        }
      ).element;
    }
    body {
      margin: 0px;
    }
    
    .container {
      background-color: #333;
      padding: 1rem;
      margin-top: 1rem;
    }
    
    .draggable {
      padding: 1rem;
      background-color: #fff;
      border: 1px solid black;
      cursor: move;
    }
    
    .draggable.dragging {
      opacity: 1;
    }
    <div class="container">
      <p id="box1" class="draggable" draggable="true">1</p>
      <p id="box2" class="draggable" draggable="true">2</p>
    </div>
    
    <div class="container">
      <p id="box3" class="draggable" draggable="true">3</p>
      <p id="box4" class="draggable" draggable="true">4</p>
    </div>