🔥 이전에 진행했던 TodoList에 Drag & Drop 이벤트를 적용시키자
Drag & Drop 이벤트란?
드래그 시작 점에서 dataTransfer라는 객체로 보낼 DOM Element를 지정하고, 드랍 하는 것이다.
순서
- 드래그 할 요소의 어트리뷰트에서 dragable이라는 속성을 true로 지정한다. (드래그 가능한 객체가 된다.)
- 드래그 시작 점 (dragstart event): 드래그한 Element를 event.dragTransfer라는 객체에 저장한다.
- 드래그 중간 === 드롭 전 (dragover event): 드롭 대상 Element의 드롭을 허용하기위해 기본동작을 취소한다.
- 드롭 시점 (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에 담아 관리할 것이다.
순서
- 일단 TaskQueue를 만든다.
- 함수가 실행되는 부분에 해당 함수를 TaskQueue에 담는다.
- 버튼을 누르면 해당 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 |