자바스크립트 드래그 앤 드롭 Drag and Drop

자바스크립트에서 Pointer Events를 사용한 드래그 앤 드롭 예제를 알아보겠습니다.

Pointer EventsMouse Events, Touch Events 등을 하나의 API로 통합하여 다양한 입력 장치에서 더 일관성 있는 이벤트 처리를 할 수 있도록 해줍니다.

드래그 앤 드롭 HTML 구조

먼저, 간단한 HTML 구조를 만들어 드래그 앤 드롭할 요소를 설정합니다.

<!DOCTYPE html>
<html lang="ko">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <style>
    #dragElement {
      width: 100px;
      height: 100px;
      background-color: skyblue;
      border: 2px solid #333;
      position: absolute;
      cursor: pointer;
    }
  </style>
</head>

<body>
  <div id="dragElement">Drag</div>

  <script src="script.js"></script>
</body>

</html>
드래그 앤 드롭 HTML

자바스크립트로 드래그 앤 드롭 기능 구현

이제 Pointer Events를 활용하여 기능을 구현할 자바스크립트 코드를 작성합니다.

const dragElement = document.getElementById('dragElement');

let offsetX = 0;
let offsetY = 0;
let isDragging = false;

dragElement.addEventListener('pointerdown', (e) => {
  isDragging = true;
  offsetX = e.clientX - dragElement.offsetLeft;
  offsetY = e.clientY - dragElement.offsetTop;

  dragElement.setPointerCapture(e.pointerId);
});

dragElement.addEventListener('pointermove', (e) => {
  if (isDragging) {
    dragElement.style.left = `${e.clientX - offsetX}px`;
    dragElement.style.top = `${e.clientY - offsetY}px`;
  }
});

dragElement.addEventListener('pointerup', () => {
  isDragging = false;
  dragElement.releasePointerCapture(event.pointerId);
});

dragElement.addEventListener('pointercancel', () => {
  isDragging = false;
  dragElement.releasePointerCapture(event.pointerId);
});
드래그 앤 드롭 기능 구현

코드 설명

  1. HTML 요소
    • dragElement라는 id를 가진 div 요소는 움직일 수 있는 영역입니다.
    • CSS에서 dragElementwidth, height, background-color 등을 설정하여 화면에 표시되게 했습니다.
  2. 자바스크립트
  3. Pointer Events – pointerdown:
    • 이는 사용자가 dragElement를 눌렀을 때 발생하는 이벤트입니다.
    • 먼저 isDragging 변수에 true를 입력하여 요소가 눌렸다는 것을 표시합니다.
    • e.clientXe.clientY를 사용하여 포인터가 눌린 좌표를 확인하고, 이를 기준으로 요소의 offset을 계산합니다.
    • setPointerCapture를 호출하여 해당 요소에 대해 캡처를 활성화합니다. 이렇게 하면 사용자가 마우스를 움직이거나 다른 곳을 클릭해도 드래그할 요소가 계속 포인터 이벤트를 받습니다.
  4. Pointer Event – pointermove:
    • 사용자가 dragElement를 끌어당기는 동안 발생하는 이벤트입니다.
    • isDraggingtrue일 때만 실행되며, 이벤트가 발생할 때 마다 요소의 위치를 포인터 위치로 갱신하여 움직이는 효과를 만듭니다.
    • e.clientXe.clientY는 포인터의 현재 위치를 나타냅니다.
  5. Pointer Event – pointerup:
    • 사용자가 마우스를 놓으면 발생하는 이벤트입니다.
    • 드래그 상태를 종료하고, releasePointerCapture를 호출하여 포인터 캡처를 해제합니다. 이를 통해 다른 포인터 이벤트가 더 이상 dragElement에 영향을 주지 않도록 합니다.
  6. Pointer Event – pointercancel:
    • 포인터 이벤트 동작 도중에 다른 이벤트가 발생하여 이벤트가 취소될 경우 발생합니다. 예를 들어, 다른 곳을 클릭하거나 포인터가 다른 장치에 의해 캡처되면 이 이벤트가 발생합니다.
    • isDraggingfalse로 설정하여 드래그 상태를 종료하고, 포인터 캡처를 해제합니다.

Pointer Events의 장점

하나의 API로 다양한 입력 장치 처리:

Pointer Events는 마우스, 터치, 펜 등 다양한 입력 장치에서 발생하는 이벤트를 일관되게 처리하게 해줍니다.

예를 들어, 터치스크린에서 드래그를 하거나 펜 입력을 사용할 수 있습니다.

포인터 캡처 기능:

setPointerCapturereleasePointerCapture를 사용하면 사용자가 화면을 클릭한 상태에서 다른 곳을 클릭해도 해당 요소가 계속 포인터 이벤트를 받을 수 있습니다.

이는 Mouse Events에서는 구현하기 어려운 부분이었습니다.

Pointer Events 주의사항

  • 브라우저 호환성: 이는 모든 브라우저에서 지원하지 않습니다. 특히 오래된 Internet Explorer(IE11 이하)에서는 Pointer Events가 지원되지 않으므로 polyfill 같은 작업을 추가로 해줘야합니다.
  • 포인터 캡쳐 관리: 포인터 캡처를 설정하면, 지정한 요소가 포인터 이벤트를 계속해서 받게 되며, 다른 곳에서 발생하는 포인터 이벤트가 무시됩니다. 따라서 캡처를 적절히 관리해야 합니다.

관련 글

자바스크립트 튜토리얼