# 22-07-06

코드스쿼드 기간 동안 프로젝트 진행과 작성을 함께 진행하기가 어렵다는 핑계로 TIL 작성에 소홀했다. 코드스쿼드 수료(7/1)도 하였으니 이제 꾸준히 작성을 해 보려 한다💪. 기록을 습관화 하여 앞으로도 꾸준히 적을 수 있도록 노력해보자🤓!

# 지난 프로젝트 돌아보기

지난 todo-list (opens new window) 프로젝트를 진행하면서 drag&drop API 없이 바닐라 JavaScript로 드래그 앤 드랍은 구현하지 못한 채로 마무리를 하였다. (대신 바닐라 JS로 React를 구현해보는 뜻깊은 시간을 보냈다😊👍)

수료 후 지난 프로젝트들을 돌아보면서, 미처 완성하지 못했던 부분을 하나씩 완성해 보려 한다💪

# 바닐라 JavaScript로 Drag & Drop 구현하기 🖱️ - 1

할 일 - 하는 중 - 끝난 일이라는 분류 내에 여러 todo 들이 있을때, 이 todo를 드래그 앤 드랍으로 분류를 이동하고, 원하는 위치(분류 내 todo들의 순서)에 위치 시키는 것이 최종 목표이다.

# 1단계 - 단 하나의 todo를 이동시키자

일단 복잡한 과제를 단순화 하여 수행해 보기로 하였다🤓. 분류 내 여러 todo 사이에 순서까지는 고려하지 않고, 단 하나의 todo만이 존재한다고 가정하여 드래그 앤 드롭을 먼저 구현해보자.

먼저 드래그 방식으로 여러 박스를 옮기기를 목표로 학습 및 구현해 본 후, 아래와 같이 진행하였다.

# 노드 복사

Node.cloneNode() (opens new window)를 이용, 선택된 todo를 복사하여 이동시에 보여주도록 하였다.

# 좌표를 이용하여 목표 container 찾기

좌표를 기준으로 도착점 container를 찾을 수 있도록, Document.elementsFromPoint() (opens new window)를 이용하여 목표 container(targetContainer)를 찾을 수 있도록 하였다.

targetContainer = document
  .elementsFromPoint(pageX - wrapOffset.x, pageY - wrapOffset.y)
  .find((el) => el.classList.contains("container"));

# mouseup 이벤트 핸들러

mouseup이벤트 발생(영역 밖으로 mouseleave이벤트 발생)시 targetContainer에 Node.appendChild() (opens new window)를 이용하여 노드를 추가해 주었다.

# 🖥️ 구현 화면

# 드래그 방식으로 여러 박스 옮기기

뉴렉처 (opens new window)의 자바스크립트 & DOM 프로그래밍 강의 48~을 참고로 여러 박스 옮기기를 구현해 보았다.

# 좌표

  • pageX, pageY : 현재 페이지(전체 스크롤 영역)를 기준으로 한 x, y좌표
  • offsetX, offsetY : 요소를 기준으로 한 x, y 좌표

# 드래그시 요소 위치를 자연스럽게 조정

  • mousedown 이벤트의 target이 box인 경우 event.offsetX, event.offsetY로 box 선택시 위치 그대로 드래그 되도록 조정

  • mousemove시 선택된 box가 있을 경우 pageX, pageY와 위에서 찾은 box의 offsetX, offsetY로 자연스러운 위치로 조정

  • pageX, pageY를 이용하므로 container의 위치까지 반영되도록 $wrap.offsetLeft, $wrap.offsetTop도 위치 계산에 적용

selectedBox.style.left = `${pageX - offset.x - $wrap.offsetLeft}px`;
selectedBox.style.top = `${pageY - offset.y - $wrap.offsetTop}px`;

# 영역 밖으로 마우스가 나갈 경우 이벤트 처리

container밖으로 mouseleave이벤트가 발생시 mouseup과 같은 이벤트 핸들러를 동작시킨다.


1단계 구현을 수행하면서 처음 사용해 보는 메소드나 Array.find()와 같이 알고는 있으나 잘 사용해 보지 않았던 메소드를 사용해 볼 수 있었다.

평소 연습을 CodeSandbox나 CodePen 등을 통해 하곤 하는데, TIL작성을 하면서 CodeSandbox의 Embed를 처음 사용해 보았다. 앞으로도 연습한 내용을 TIL에 작성 하는 데에 유용하게 사용할 수 있을 듯 😆