SDWoo
SDWoo의 개발일기
SDWoo
전체 방문자
오늘
어제
  • 분류 전체보기 (21)
    • 데브코스 (4)
    • TIL (13)
    • javascript (4)
    • react (0)
    • 알고리즘 (0)

블로그 메뉴

  • 홈
  • 태그
  • 방명록
  • 글쓰기

공지사항

인기 글

태그

  • Til
  • 알고리즘
  • 호이스팅
  • This
  • 프로그래머스
  • addEventListener
  • 신규 아이디 추천
  • Spread문법
  • vanilaJS
  • intersectionobserver
  • 비동기
  • Promise
  • deepdiv
  • 이벤트루프
  • 무한스크롤
  • 데브코스
  • 디스트럭처링할당
  • 제네레이터
  • RESTAPI 설계 원칙 #까먹지말것
  • JavaScript
  • linkedlist
  • 선형
  • javascrip
  • JavaScript #TIL #VanillaJS
  • cypress
  • es6
  • async/await
  • vanillajs
  • Typing-Game
  • 행맨

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
SDWoo

SDWoo의 개발일기

[VanillaJS] TodoList에 Drag & Drop 이벤트 적용시키기 (feat. taskQueue)
데브코스

[VanillaJS] TodoList에 Drag & Drop 이벤트 적용시키기 (feat. taskQueue)

2022. 11. 24. 01:16

🔥 이전에 진행했던 TodoList에 Drag & Drop 이벤트를 적용시키자

Drag & Drop 이벤트란?

드래그 시작 점에서 dataTransfer라는 객체로 보낼 DOM Element를 지정하고, 드랍 하는 것이다.

순서

  1. 드래그 할 요소의 어트리뷰트에서 dragable이라는 속성을 true로 지정한다. (드래그 가능한 객체가 된다.)
  2. 드래그 시작 점 (dragstart event): 드래그한 Element를 event.dragTransfer라는 객체에 저장한다.
  3. 드래그 중간 === 드롭 전 (dragover event): 드롭 대상 Element의 드롭을 허용하기위해 기본동작을 취소한다.
  4. 드롭 시점 (drop event): 일부 요소의 링크 열기와 같은 기본동작 취소 후, 드래그한 요소를 event.dragTransfer객체에서 가져와 드롭 대상으로 이동한다.

실습

// example
// render 
this.render = () => {
    $target.innerHTML = `
      <li dragable="true" class=".element">name</li>
    `
}
// 드래그 시작 점
document.addEventListener('dragstart', (e) => {
  $element = document.querySelector('.element');
  e.dragTransfer.setItem('element', $element);
   // (key, value) 형태로 dataTransfer객체에 저장
})

// 드래그 중일 경우
document.addEventListener('dragover', (e) => {
  // 드롭 대상 element의 드롭을 허용하기 위해 기본동작을 취소한다.
  e.preventDefault(); 
  // 드래그 중의 이미지가 다르게 표시된다. 
  // e.dropEffect에는 move(그냥), copy(+), link(화살표), none() 네가지 옵션이 있다.
  e.dropEffect = 'move';
})

// 드롭할 경우
document.addEventListener('drop', (e) => {
  // 기본동작이 드롭하지 않는 것이기 때문에 무시해줘야 함.
  e.preventDefault();

  // dataTransfer객체에 저장해 두었던 값을 가져다 씀
  const droppedData = e.dataTransfer.getData('element');
  onDrop(droppedData); // drop시 함수실행
})

이렇게 drag, drop 이벤트가 아닌 마우스 이벤트로 하는 경우도 있다고 한다. (나중에 정리)

‼️ TaskQueue

  • 드래그, 드랍시에 계속해서 API 통신을 하기 때문에, 쓸데없는 API 통신이 많아질 수 있다.
  • 이것을 해결하기 위해 TaskQueue에 동작들을 저장해두었다가, 특정 조건에 맞으면 일괄적으로 실행된다.
  • 오늘은 데이터 toggle과 remove 함수들을 TaskQueue에 담아 관리할 것이다.

순서

  1. 일단 TaskQueue를 만든다.
  2. 함수가 실행되는 부분에 해당 함수를 TaskQueue에 담는다.
  3. 버튼을 누르면 해당 TaskQueue에 있던 함수들이 순차적으로 실행된다.

실습

- TaskQueue.js
export default function TaskQueue() {
    let tasks = []; // const 로 바꿀 수 있는 방법을 연구해봐야겠다.

    this.addTask = (task) => {
        tasks.push(task);
    }

    this.removeTask = (url) => {
        tasks = tasks.filter((task) => !task.url.includes(url));
    }

    // 재귀함수로 구현해 task안에 있는 요소들을 다 실행시킬 수 있게함
    this.run = async () => {
        if(tasks.length > 0) {
          const task = tasks.shift();

          // request는 api 통신을 위한 함수 (fetch)
          await request(task.url, {
              method: task.method || 'GET',
          });
          this.run();
        }
    }
}

- App.js
...

const tasks = new TaskQueue();
const handlePutDrop = (id) => {
    ...
    taskQueue.addTask({
      url: `/${id}`,
      method: 'PUT'
    })
}
const handleRemoveDrop = (id) => {
    ...
    taskQueue.removeTask(`/${id}`) // 중복 요소가 있다면 먼저 제거
    taskQueue.addTask({
      url: `/${id}`,
      method: 'Remove'
    })
}

...

$button.addEventListener('click', () => {
    taskQueue.run();
});

...

🔎 마무리

  • 오늘은 이렇게 Drag & Drop 이벤트에 대해 알아보았다.
  • 너무 재밌었다. 😊
  • 나에게 스스로 질문을 많이 던지며 코딩해보니까 더 재밌었던 것 같다.

🧐 오늘의 Why?

  • return ; 과 throw new Error 중 어떤것이 좋은 것인가? (어떤 상황에 어떤 것을 써야 하는가?)
    => 둘 다 같은 역할을 하지만, return은 function을 끝마칠 때 사용하고 특정 값을 반환한다,
    throw new Error는 함수가 기능을 제대로 종료하고 기본적으로 처리되지 않으면 코드를 중지할 때 사용되고 모든 오류를 포착한다. (try catch)
    => 주의해야할 점: 예외처리할 때 주의하지 않으면 모든 오류를 포착해서 코드 내부의 특정 버그가 숨겨질 수도 있다
    => 좀 더 알아보고 정리할 필요가 있을 것 같다.
  • nextState의 정합성 검사는 어떻게 해야 좋을까 ?
    => 원래 state와 nextState 타입 검사 - 다르면 setState 안함
    => state의 값이 nextState와 같은지 검사 - 다르면 setState 실행 안함
    => nextState의 내부 요소 타입 검사 - 다르면 setState 실행 안함
  • taskQueue를 사용한 이유는?
    => 계속해서 같은 이벤트가 날라오면 트래픽이 많으면 느려질 수 있다
    => 비슷한 개념으로 requsetAnimationFrame이 있다고 해서 내일 알아볼 예정이다.

'데브코스' 카테고리의 다른 글

VanillaJS를 통한 자바스크립트 정리 2  (0) 2022.11.02
VanillaJS를 통한 자바스크립트 정리 1  (0) 2022.10.31
프로그래머스 데브코스 2주차 회고록 😝  (0) 2022.10.31
    '데브코스' 카테고리의 다른 글
    • VanillaJS를 통한 자바스크립트 정리 2
    • VanillaJS를 통한 자바스크립트 정리 1
    • 프로그래머스 데브코스 2주차 회고록 😝
    SDWoo
    SDWoo

    티스토리툴바