[HTML]드래그 앤 드롭(drag and drop) API

Hyodduru ·2022년 1월 30일
0

HTML & CSS

목록 보기
8/13
post-thumbnail

드래그 앤 드롭 API는 웹 페이지 내의 요소를 사용자가 자유롭게 드래그할 수 있도록 설정해준다. 웹 페이지 내의 모든 요소는 draggable 속성을 사용하여 드래그될 수 있는 객체(draggable object)로 변환될 수 있다.

드래그 앤 드롭 이벤트

✅ dragstart : 사용자가 객체(object)를 드래그하려고 시작할 때 발생함.
✅ dragenter : 마우스가 대상 객체의 위로 처음 진입할 때 발생함.
✅ dragover : 드래그하면서 마우스가 대상 객체의 위에 자리 잡고 있을 때 발생함.
✅ drag : 대상 객체를 드래그하면서 마우스를 움직일 때 발생함.
✅ drop : 드래그가 끝나서 드래그하던 객체를 놓는 장소에 위치한 객체에서 발생함.
✅ dragleave : 드래그가 끝나서 마우스가 대상 객체의 위에서 벗어날 때 발생함.
✅ dragend : 대상 객체를 드래그하다가 마우스 버튼을 놓는 순간 발생함.

이벤트 활용

드래그를 함으로써 드래그가 시작된 위치와 끝나는 위치의 아이템을 바꾸는 기능을 실현해보자

HTML

<ul class="draggable-list" id="draggable-list"></ul>

CSS

.draggable-list li.over .draggable {
  background-color: #eaeaea;
}

JavaScript

자바스크립트 내에서 동적으로 list들을 만들어준다.

const draggable_list = document.getElementById("draggable-list");

const richestPeople = [
  "Jeff Bezos",
  "Bill Gates",
  "Warren Buffett",
  "Bernard Arnault",
  "Carlos Slim Helu",
  "Amancio Ortega",
  "Larry Ellision",
  "Mark Zuckerberg",
  "Michael Bloomberg",
  "Larry Page",
];

// Store list items
const listItems = [];

createList();

function createList() {
  [...richestPeople]
    .map((a) => ({ value: a, sort: Math.random() }))
    .sort((a, b) => a.sort - b.sort)
    .map((a) => a.value)
    .forEach((person, index) => {
      const listItem = document.createElement("li");
      listItem.setAttribute("data-index", index);
      listItem.innerHTML = `
         <span class="number">${index + 1}</span> 
         <div class="draggable" draggable="true">
          <p class="person-name">${person}</p>
          <i class="fas fa-grip-lines"></i>
         </div>       `;

      listItems.push(listItem);
      draggable_list.appendChild(listItem);
    });

  addEventListeners();
}

function dragStart() {
  dragStartIndex = this.dataset.index;
}

function dragEnter() {
  this.classList.add("over");
}

function dragLeave() {
  this.classList.remove("over");
}
function dragOver(e) {
  e.preventDefault();
}
function dragDrop() {
  this.classList.remove("over");
  const dragEndIndex = this.dataset.index;

  swapItems(dragStartIndex, dragEndIndex);
}

function swapItems(fromIndex, toIndex) {
  const itemOne = listItems[fromIndex].querySelector(".draggable");
  const itemTwo = listItems[toIndex].querySelector(".draggable");

  listItems[fromIndex].appendChild(itemTwo);
  listItems[toIndex].appendChild(itemOne);
}


function addEventListeners() {
  const dragListItems = draggable_list.querySelectorAll("li");

  dragListItems.forEach((item) => {
    item.addEventListener("dragstart", dragStart);
    item.addEventListener("dragover", dragOver);
    item.addEventListener("drop", dragDrop);
    item.addEventListener("dragenter", dragEnter);
    item.addEventListener("dragleave", dragLeave);
  });
}

드래그가 시작되는 아이템의 인덱스와, 끝나는 인덱스를 인자로 받는 swapItems 함수에서 직접 list내의 드래그 되는 내용을 바꾸어준다.

참고로, dragover 이벤트는 매 millisecond마다 발생하기 때문에 이벤트 기능을 막아줌으로써 drop 이벤트를 실행시킬 수 있게끔 만든다.

profile
꾸준히 성장하기🦋 https://hyodduru.tistory.com/ 로 블로그 옮겼습니다

0개의 댓글