// html
const { title, todos = [] } = this.state
$todoList.innerHTML = `
<h2>${title}</h2>
<ul>
${todos.map(todo => `<li data-id="${todo._id}" draggable="true">${todo.content}</li>`).join('')}
</ul>
${todos.length === 0 ? '설정된 일이 없습니다.' : ''}
`
// script
$todoList.addEventListener('dragstart', e => {
const $li = e.target.closest('li')
e.dataTransfer.setData('todoId', $li.dataset.id)
})
$todoList.addEventListener('dragover', (e) => {
e.preventDefault()
e.dataTransfer.dropEffect = 'move'
})
$todoList.addEventListener('drop', e => {
e.preventDefault()
const droppedTodoId = e.dataTransfer.getData('todoId')
const { todos } = this.state
if (!todos.find(todo => todo._id === droppedTodoId)) {
onDrop(droppedTodoId)
}
})
drag & drop api를 간단히 말하자면, draggable속성을 이용해 요소를 드래그 할 수 있고, droppable을 이용해 요소를 드롭할 수 있다는 것이다.
사용방법은 드래그를 위해 html태그에 draggable="true"를 추가하고 draggable attribute를 설정하여야 하고, 드래그한 요소를 받는 droppable 설정을 위해서 드래그 한 파일이 영역안에 들어올 때 발생하는 ondragover와 드래그를 뗐을 때 발생하는 ondrop이벤트 속성을 가져야 한다.
드래그한 데이터를 받기 위해서는 setData, setDragImage를 통해 드래그할 때 옮길 데이터를 추가하고, getData를 통해 드래그 한 데이터를 받도록 설정하여야 한다.
dropEffect를 통해 드래그 효과를 정의할 수 있으며, html에서 기본적으로 막혀있는 ondragover을 event.preventDefault()을 통해 ondragover을 작동하도록 만들 수 있다.
자바스크립트는 싱글스레드이지만, Web Worker는 이를 실행하는 브라우저에서 script를 백그라운드 쓰레드에서 실행할 수 있도록 해주는 기술이다. 이 기술을 통해 무거운 작업을 분리된 쓰레드에서 처리할 수 있으며, 이를 통해 메인 쓰레드(일반적으로 UI 쓰레드)는 멈춤, 속도저하 없이 동작할 수 있게 해준다.
주의할 점은 병렬적으로 작동하다 보니 싱글코어의 cpu에서는 효과가 없다. 또한 워커는 DOM에 접근하지 못하며, 사용할 수 있는 API에 제약이 있으니, 사용 가능한 목록을 확인하는 것이 좋다.
참고사이트 MDN 드래그앤드롭, MDN 웹워커, 제로초 웹워커