자바스크립트에서 Pointer Events
를 사용한 드래그 앤 드롭 예제를 알아보겠습니다.
Pointer Events
는 Mouse Events
, Touch Events
등을 하나의 API로 통합하여 다양한 입력 장치에서 더 일관성 있는 이벤트 처리를 할 수 있도록 해줍니다.
Table of Contents
드래그 앤 드롭 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>

자바스크립트로 드래그 앤 드롭 기능 구현
이제 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);
});

코드 설명
- HTML 요소
dragElement
라는 id를 가진div
요소는 움직일 수 있는 영역입니다.- CSS에서
dragElement
에width
,height
,background-color
등을 설정하여 화면에 표시되게 했습니다.
- 자바스크립트
- getElementById() 메소드를 사용하여
dragEelement
변수에 요소를 저장합니다.
- getElementById() 메소드를 사용하여
- Pointer Events –
pointerdown
:- 이는 사용자가
dragElement
를 눌렀을 때 발생하는 이벤트입니다. - 먼저 isDragging 변수에 true를 입력하여 요소가 눌렸다는 것을 표시합니다.
e.clientX
와e.clientY
를 사용하여 포인터가 눌린 좌표를 확인하고, 이를 기준으로 요소의 offset을 계산합니다.setPointerCapture
를 호출하여 해당 요소에 대해 캡처를 활성화합니다. 이렇게 하면 사용자가 마우스를 움직이거나 다른 곳을 클릭해도 드래그할 요소가 계속 포인터 이벤트를 받습니다.
- 이는 사용자가
- Pointer Event –
pointermove
:- 사용자가
dragElement
를 끌어당기는 동안 발생하는 이벤트입니다. isDragging
이true
일 때만 실행되며, 이벤트가 발생할 때 마다 요소의 위치를 포인터 위치로 갱신하여 움직이는 효과를 만듭니다.e.clientX
와e.clientY
는 포인터의 현재 위치를 나타냅니다.
- 사용자가
- Pointer Event –
pointerup
:- 사용자가 마우스를 놓으면 발생하는 이벤트입니다.
- 드래그 상태를 종료하고,
releasePointerCapture
를 호출하여 포인터 캡처를 해제합니다. 이를 통해 다른 포인터 이벤트가 더 이상dragElement
에 영향을 주지 않도록 합니다.
- Pointer Event –
pointercancel
:- 포인터 이벤트 동작 도중에 다른 이벤트가 발생하여 이벤트가 취소될 경우 발생합니다. 예를 들어, 다른 곳을 클릭하거나 포인터가 다른 장치에 의해 캡처되면 이 이벤트가 발생합니다.
isDragging
을false
로 설정하여 드래그 상태를 종료하고, 포인터 캡처를 해제합니다.
Pointer Events의 장점
하나의 API로 다양한 입력 장치 처리:
Pointer Events
는 마우스, 터치, 펜 등 다양한 입력 장치에서 발생하는 이벤트를 일관되게 처리하게 해줍니다.
예를 들어, 터치스크린에서 드래그를 하거나 펜 입력을 사용할 수 있습니다.
포인터 캡처 기능:
setPointerCapture
와 releasePointerCapture
를 사용하면 사용자가 화면을 클릭한 상태에서 다른 곳을 클릭해도 해당 요소가 계속 포인터 이벤트를 받을 수 있습니다.
이는 Mouse Events
에서는 구현하기 어려운 부분이었습니다.
Pointer Events 주의사항
- 브라우저 호환성: 이는 모든 브라우저에서 지원하지 않습니다. 특히 오래된 Internet Explorer(IE11 이하)에서는
Pointer Events
가 지원되지 않으므로polyfill
같은 작업을 추가로 해줘야합니다. - 포인터 캡쳐 관리: 포인터 캡처를 설정하면, 지정한 요소가 포인터 이벤트를 계속해서 받게 되며, 다른 곳에서 발생하는 포인터 이벤트가 무시됩니다. 따라서 캡처를 적절히 관리해야 합니다.