devSoyoung / STUDY

✏️ 공부한 내용 정리, 주제에 따라 분류
4 stars 1 forks source link

[HTML5] Drag and Drop API #7

Open devSoyoung opened 5 years ago

devSoyoung commented 5 years ago

드래그 앤 드롭 기능이 필요한 프로젝트가 있었는데, 직접 구현하니 코드가 매우 길어졌습니다 :( 좌표를 일일히 계산해서 mousemove 이벤트가 발생할 때 엘리먼트를 옮겨주어야 하는데, mousedown이 일어난 후의 mousemove만 감지하기 위해서 flag를 사용해서 체크해주어야 하는 등 번거로움이 많았습니다.

이 부분에 대하여 코드 리뷰를 받고, Drag and Drop API에 대해 알게 되어서 활용할 겸, 정리하게 되었습니다.

Drag Event

드래그 앤 드롭은 꽤 자주 사용되는 동작입니다. 이전까지는 개발자가 마우스 이벤트에 핸들러를 달아서 직접 구현해주어야 했지만, HTML5에서는 표준이 되었습니다. 어떤 요소든 쉽게 드래그 가능한 요소로 만들어 줄 수 있습니다.

드래그는 보통 다음과 같은 동작으로 구성됩니다.

1. draggable 요소를 마우스로 선택한다.
2. 마우스 포인터를 이동한다.
3. droppable 요소에서 마우스 버튼을 뗀다.

드래그와 관련된 이벤트는 다음과 같습니다.

이벤트 핸들러 설명
darg ondrag 요소나 텍스트 블록을 드래그 할 때 발생합니다.
dragend ondragend 드래그가 끝났을 때(마우스 버튼을 떼거나, ESC 키를 누를 때) 발생합니다.
dragenter ondragenter 드래그한 요소나 텍스트 블록이 적합한 드롭 대상 위에 올라갔을 때 발생합니다.
dragexit ondragexit 요소가 더 이상 드래그의 직접적인 대상이 아닐 때 발생합니다.
dragleave ondragleave 드래그하는 요소나 텍스트 블록이 적합한 드롭 대상에서 벗어났을 때 발생합니다.
dragover ondragover 요소나 텍스트 블록을 적합한 드롭 대상 위치로 지나갈 때 발생합니다.
dragstart ondragstart 사용자가 요소나 텍스트 블록을 드래그하기 시작했을 때 발생합니다.
drop ondrop 요소나 텍스트 블록을 적합한 드롭 대상에 드롭했을 때 발생합니다.

참고링크에 연결해 둔, MDN의 HTML 드래그 앤 드롭 API에서 참조한 표입니다. 표만 보아서는 dragexit 이벤트와 dragleave 이벤트가 잘 구분이 가지 않아서 예제를 만들어서 실행해보기로 했습니다.

Drag Event Example

간단한 HTML 파일을 작성해봅니다.

<!doctype html>  
<html lang="ko">  
<head>  
    <meta charset="utf-8">  
    <title>HTML Test</title>  
    <link rel="stylesheet" type="text/css" href="src/main.css"/>  
    <script src="src/main.js"></script>  
</head>  
<body>  
    <div class="drag-item" draggable="true"></div>  
</body>  
</html>

어떤 엘리먼트의 draggable 속성 값을 true로 주면, 해당 요소는 드래그 가능한 요소가 됩니다. 드래그 요소를 좀 더 명확하게 볼 수 있도록 간단한 스타일도 지정해줍니다.

.drag-item {  
  width: 100px;  
  height: 100px;  
  background-color: coral;  
}  

.drag-item:hover {  
  cursor: pointer;  
}

화면에는 가로, 세로 100px의 코랄색 네모 상자가 생겼고, 마우스를 올리면 포인터로 커서가 바뀝니다. 드래그하면, 반투명해진 요소가 포인터를 따라다닙니다. 이제 drag 이벤트를 등록해봅니다.

drag 이벤트 등록

(function() {  
  const dragEl = document.querySelector(`.drag-item`);  
  dragEl.addEventListener(`drag`, event => {  
    console.log(`drag 이벤트가 발생했습니다.`);  
    console.log(event);  
  })  
})();

다시 요소를 드래그하면 엄청 많은 drag 이벤트가 발생하고 있다는 것을 확인할 수 있습니다.

image

참고링크