Drag & Drop API

Jung taeWoong·2021년 7월 7일
1

javascript

목록 보기
6/8
post-thumbnail

Drag & Drop API

Browser App 에서 Drag & Drop 기능을 사용하게 해주는 API
아직까지 🐛의 문제점이 많다.

1. Drag 하려는 HTML 요소 draggable="true" 속성 추가

<div draggable="true"></div>

Drag 하는동안 draggable 요소는 반투명한 채로 마우스 포인터를 따라다닌다.

2. Drag Event Listener 등록

HTML 드래그 앤 드롭은 DOM event model 과 drag events 를 mouse events 로부터 상속받습니다. 보통 드래그는 사용자가 draggable 요소를 마우스로 선택하고, 마우스 포인터를 droppable 요소로 가져가 마우스 버튼을 때는 것으로 이루어집니다. 드래그하는 도중에 많은 이벤트가 발생하고, 몇몇 이벤트는 여러번 발생하기도 합니다.

이벤트설명
dragstartDrag 시작할때 이벤트 발생
dragEndDrag를 끝냇을때 이벤트 발생
dragEnterDarg하는 요소를 Drop 대상위에 올라갔을때 이벤트 발생
dragLeaveDrag하는 요소가 Drop 대상에서 벗어났을때 발생

3. Drop 지역 정의하기

기본적으로는 브라우저는 HTML 요소에 뭔가를 드롭했을 때 아무 일도 일어나지 않도록 합니다. 특정 요소가 드롭 지역 혹은 droppable로 만들기 위해서는 해당 요소가 ondragover (en-US)와 ondrop (en-US) 이벤트 핸들러 속성을 가져야합니다.

Drop 지역 요소에 dragoverdrop 이벤트 핸들러 연결
위 두개의 이벤트 핸들러에서 preventDefault()를 꼭 추가해주어야 한다.

각 핸들러는 preventDefault() 를 호출해 추가적인 이벤트 (터치 이벤트나 포인터 이벤트) 가 일어나지 않도록 합니다.

dropElement.addEventListener('dragover', (event) => {
  event.preventDefault();
});

dropElement.addEventListener('drop', (event) => {
  event.preventDefault();
});

4. 🐛Bug 문제점

Drag & Drop API의 대표적인 버그로 DragEnter DragLeave 이벤트가 draggable="true"요소의 자식들에게도 발생하는 문제

해결방법

Drag하는 동안 다른 draggable="true" 요소의 자식들을 pointer-events: none 설정

.mute-children * {
  pointer-events: none;
}
dragElement.addEventListener('dragstart', event => {
  document.querySelectorAll('[draggable="true"]')
    .forEach(item => item.classList.add('mute-children');
  
  ...logic
});
dragElement.addEventListener('dragend', event => {
   document.querySelectorAll('[draggable="true"]')
    .forEach(item => item.classList.remove('mute-children');
  
  ...logic
});
profile
Front-End 😲

0개의 댓글