본문 바로가기
javaScript

드래그 앤 드롭의 시작! mousedown과 mousemove로 배우는 DOM 이벤트

by mooyou 2025. 6. 29.
728x90
300x250
SMALL

웹에서 자바스크립트를 활용한 인터랙션 중 가장 많이 쓰이는 기능 중 하나가 바로 드래그 입니다. 드래그 기능은 마우스를 누르고 끌어서 요소를 이동하거나, 크기를 조절하거나, 다양한 동작을 유도할 수 있게 해줍니다.

 


 

1. 마우스 관련 이벤트란?

자바스크립트에서 마우스를 이용한 주요 이벤트는 다음과 같다

이벤트 설명
mousedown 마우스 버튼을 누를 때 발생
mousemove 마우스를 움직일 때 발생
mouseup 마우스 버튼을 뗄 때 발생

 

이 세 가지를 조합하면 드래그를 구현할 수 있다.

 


 

2. 가장 기본적인 구조

드래그 기능의 기본 흐름은 아래와 같다.

// 1. 마우스를 누르면 시작 위치를 기억
box.addEventListener('mousedown', (e) => {
  startY = e.clientY;
});

// 2. 마우스를 움직이면 이동 거리를 계산
window.addEventListener('mousemove', (e) => {
  const deltaY = e.clientY - startY;
  box.style.transform = `translateY(${deltaY}px)`;
});

// 3. 마우스를 떼면 드래그 종료
window.addEventListener('mouseup', () => {
  // 초기화 또는 최종 상태 설정
});

 

하지만 실제로 조건문, 플래그 등을 이용해 드래그 중인 상태를 구분해줘야 한다.

 

  • e.clientY는 마우스가 현재 위치한 Y 좌표
  • startY는 드래그 시작할 때의 Y좌표
  • 둘의 차이(deltaY)는 드래그한 거리
  • Y축 방향으로 deltaY만큼 이동시킴
  • 실제 위치를 바꾸는 것이 아니라 보이는 위치를 이동시켜준다.

 

3. 예제 : 사각형 박스를 드래그하기

html

<div id="box">드래그해보세요</div>

 

css

#box {
  width: 200px;
  height: 100px;
  background: #3498db;
  color: white;
  display: flex;
  align-items: center;
  justify-content: center;
  position: absolute;
  top: 100px;
  left: 100px;
  cursor: grab;
}

 

js

const box = document.getElementById('box');
let isDragging = false;
let offsetX = 0;
let offsetY = 0;

box.addEventListener('mousedown', (e) => {
  isDragging = true;
  offsetX = e.clientX - box.offsetLeft; // 마우스를 누른 위치에서, 박스의 왼쪽 위치를 뺀 것 드래그할 때 박스가 튀지 않게 하기 위해 이 값을 저장
  offsetY = e.clientY - box.offsetTop;
  box.style.cursor = 'grabbing'; // 마우스를 누르고 있을 때 손 모양 커서를 바꿔준다.
});

window.addEventListener('mousemove', (e) => {
  if (!isDragging) return; //마우스를 누륵 있지 않다면 실행하지 않고 그냥 return
  box.style.left = `${e.clientX - offsetX}px`;
  box.style.top = `${e.clientY - offsetY}px`;
});

window.addEventListener('mouseup', () => {
  isDragging = false;
  box.style.cursor = 'grab';//드래그가 끝나고 마우스를 떼면 다시 기본 커서 상태로 돌아감
});

 

  • clientX, clientY는 화면에서의 마우스 위치를 나타낸다.(화면기준)
  • box.offsetLeft 박스(요소)가 문서의 왼쪽에서 얼마나 떨어졌는지를 나타낸다. 즉 박스의 현재 위치
  • if (!isDragging) return; 드리그 중일 때만 mousemove가 작동하도록 막는 안전장치
  • e.clientX - offsetX는 마우스 위치에 offset 값을 빼서, 박스의 좌측이 정확히 마우스 위치에 맞춰지도록 계산
  • offsetX를 고려하지 않으면, 마우스 위치와 박스가 어긋나게 움직인다.
  • 요소의 위치를 직접 수정하려면 style.left, style.top을 사용하거나 transform을 쓸 수 있다.
  • mousedown에서 시작 좌표를 저장하고, mousemove에서 이동량을 계산해 적용하면 드래그 기능이 구현된다.
728x90
반응형
LIST

댓글