드래그 앤 드롭은 사용자 상호 작용을 향상시키고 원활한 사용자 경험을 촉진하는 필수 기능입니다. 파일 업로더, 정렬 가능한 목록, 인터랙티브 게임을 만들 때 이 API의 기능을 활용하는 방법을 이해하는 것은 웹 개발 툴킷에서 갖춰야 할 중요한 기술입니다.
HTML 드래그 앤 드롭의 기초
첫 번째 범주는 마우스와 같은 포인팅 장치를 사용하여 조작할 수 있는 객체를 포함하며, 이를 “드래그 가능한” 요소라고 하고, 두 번째 범주는 이러한 요소를 배치하기 위해 지정된 리셉터클 또는 대상 영역으로 구성되며, 이를 “드롭 가능한” 컴포넌트라고 합니다.
웹 애플리케이션에서 드래그 앤 드롭 기능을 사용하려면 마우스를 통해 조작할 요소를 지정해야 합니다. 사용자가 커서로 객체를 이동할 수 있도록 하려면 아래 그림과 같이 해당 HTML 태그에 “드래그 가능” 속성이 “true”로 설정되어 있어야 합니다:
<div draggable="true">This element is draggable</div>
사용자가 생성한 드래그 이벤트를 통해 드래그 작업을 시작하면 최신 웹 브라우저는 일반적으로 현재 조작 중인 요소를 시각적으로 표시하기 위해 기본 플레이스홀더 또는 “고스트” 표현을 제공합니다. 이 고스트 이미지는 드래그 앤 드롭 프로세스 중에 즉각적인 피드백의 한 형태로 사용됩니다.
이 시각적 요소를 대체 그래픽으로 개인화하려면 기본 그림 대신 선택한 그림으로 대체할 수 있습니다. 이렇게 하려면 문서 객체 모델(DOM) 내에서 이동 가능한 구성 요소를 선택하고 맞춤형 피드백 그림을 상징하는 새로운 이미지를 생성한 다음 아래 제공된 예와 유사한 드래그 시작 드래그 이벤트 리스너를 구현합니다:
let img = new Image();
img.src = 'https://upload.wikimedia.org/wikipedia/commons/thumb/9/90/Twemoji_1f600.svg/220px-Twemoji_1f600.svg.png';
document.querySelector('div').addEventListener('dragstart', (event)=>{
event.dataTransfer.setDragImage(img, 10, 10);
})
`TimelineItem` 클래스 내의 `setDragImage` 함수 구현에는 세 개의 매개 변수가 포함됩니다. 초기 매개변수는 원하는 이미지에 대한 참조이며, 이후 두 매개변수는 드래그 동작 중에 해당 이미지의 수평 및 수직 변위 좌표를 지정하는 데 사용됩니다. 웹 브라우저를 통해 이 코드를 실행하면 이전에 지정한 사용자 지정 드래그 이미지가 적용되어 일반적으로 드래그 앤 드롭 작업과 관련된 기본 표현을 효과적으로 대체합니다.
커서를 따라가는 요소의 자연스러운 경향을 재정의하려면 ‘드래그 엔터’ 및 ‘드래그 오버’ 이벤트와 관련된 표준 기능을 억제하는 것이 필수적입니다. 이렇게 하면 마우스 포인터를 따라 객체가 드래그되는 기존 동작을 효과적으로 중단할 수 있습니다.
const dropElement = document.querySelector("drop-target");
dropElement.addEventListener("dragenter", (ev) => {
ev.preventDefault();
});
dropElement.addEventListener("dragover", (ev) => {
ev.preventDefault();
});
DragEvent 인터페이스 이해
자바스크립트 언어에는 사용자가 시작한 드래그 앤 드롭 동작과 관련된 상호 작용을 나타내는 “DragEvent”라는 인터페이스가 포함되어 있습니다. 아래에 설명된 것처럼 다양한 잠재적 이벤트 유형이 이 인터페이스의 범위에 속합니다:
드래그 동작을 통해 요소를 적극적으로 이동하는 동안 사용자가 이 이벤트를 트리거합니다.
사용자가 마우스 버튼에서 손을 떼거나 이스케이프 키를 눌러 작업을 취소하는 등 드래그 작업이 종료되면 “dragend” 이벤트가 트리거됩니다.
드래그한 요소가 유효한 드롭 대상에 들어가면 “드래그 엔터” 이벤트가 트리거됩니다.
끌어서 놓기 작업 중 드래그한 요소가 유효한 놓기 대상의 위 또는 위에 더 이상 있지 않을 때 “dragleave” 이벤트가 트리거됩니다. 이 이벤트는 드래그 동작이 중단되었음을 나타내며 애플리케이션이 적절하게 응답할 수 있는 기회를 제공합니다.
사용자가 보조 키를 누른 상태에서 유효한 드롭 대상 위로 커서를 이동하거나 터치 디바이스를 탭하여 드래그 작업을 시작하면 드래그 오버 이벤트가 트리거됩니다. 이 이벤트를 통해 개발자는 잠재적인 드롭에 대비하고 실제로 다른 요소에 드롭하기 전에 요소의 모양을 적절히 수정할 수 있습니다.
드래그 동작이 시작될 때 드래그 시작 이벤트가 트리거됩니다.
사용자가 지정된 드롭 영역 위에 있는 아이템을 놓거나 놓는 동작을 실행하면, 이러한 동작의 대상이 되는 “드롭”이라는 특정 이벤트가 발생합니다.
외부 파일 관리 도구와 같이 웹 브라우저의 인터페이스 외부에서 파일과 상호 작용할 때 브라우저가 ‘드래그 시작’ 또는 ‘드래그렌드’ 발생을 시작하지 못합니다.
프로그래밍 수단을 통해 사용자 지정 드래그 이벤트를 시작하려고 할 때 ‘드래그 이벤트’ 객체를 활용하면 유리할 수 있습니다. 예를 들어 웹페이지를 로드할 때 특정 요소에 대해 고유한 드래그 이벤트를 트리거하고 싶다고 가정해 보겠습니다. 이러한 시나리오에서는 다음 단계를 따를 수 있습니다: 1. 사용자 지정 드래그 이벤트의 기반이 될 `DragEvent()` 생성자의 새 인스턴스를 생성합니다. 이 작업은 `new` 키워드 뒤에 원하는 이벤트의 이름과 괄호를 중괄호로 묶어 호출하여 수행할 수 있습니다. 2. 생성 중인 사용자 지정 드래그 이벤트와 관련된 추가 속성 또는 매개변수를 지정합니다.여기에는 드래그 작업 유형(예: 이동, 크기 조정), 드래그 이벤트와 관련된 소스 요소,
const customDragStartEvent = new DragEvent('dragstart', {
dataTransfer: new DataTransfer(),
})
const customDragEndEvent = new DragEvent('dragend');
앞서 언급한 코드 블록은 `customDragStartEvent`가 `DragEvent()` 객체의 인스턴스화이며, 그 구조체 내에 두 개의 지정된 매개변수를 포함하고 있음을 보여줍니다. 참고로 초기 매개변수는 앞서 열거한 7가지 가능한 범주 중 하나를 포함하는 특정 종류의 ‘드래그’ 이벤트를 나타냅니다.
프로세스를 시작하려면 먼저 주어진 객체와 연관된 특정 인스턴스 `DataTransfer`를 식별해야 합니다. 이는 “dataTransfer” 키로 알려진 속성을 검사하여 수행할 수 있습니다. 그 다음에는 문서 객체 모델(DOM) 내에서 원하는 요소에 대한 액세스 권한을 확보해야 하며, 이를 통해 이벤트를 시뮬레이션하는 데 필요한 작업을 구현할 수 있습니다.
const draggableElement = document.querySelector("#draggable");
“ID가 89 인 객체가 부모 컨테이너에 연결된 이벤트 리스너에 의해 선택되었습니다.” 이는 JavaScript 코드가 올바르게 작동하고 있으며 웹 페이지의 HTML 요소에서 이벤트를 수신하고 있음을 나타냅니다.
draggableElement.addEventListener('dragstart', (event) => {
console.log('Drag started!');
event.dataTransfer.setData('text/plain', 'Hello, world!');
});
draggableElement.addEventListener('dragend', () => {
console.log('Drag ended!');
});
초기 이벤트 리스너는 콜백 함수를 사용하여 “드래그가 시작되었습니다!”라는 메시지를 기록하는 동시에 ‘설정’을 호출합니다. “라는 메시지를 기록하는 동시에 이벤트 객체의 `dataTransfer` 속성에서 `setData` 메서드를 호출합니다. 이를 통해 비슷한 방식으로 사용자 정의 이벤트를 생성할 수 있습니다.
draggableElement.dispatchEvent(customDragStartEvent);
draggableElement.dispatchEvent(customDragEndEvent);
데이터 전송으로 데이터 전송
드래그 앤 드롭 작업 중에 데이터 전송 개체는 드래그 가능한 항목인 원본 요소와 드롭 가능한 영역인 수신자를 연결하는 중간 구조로 작동합니다. 이 객체는 이 두 요소 간에 공유하려는 정보를 임시로 저장합니다.
제공된 데이터는 텍스트 콘텐츠, 균일한 리소스 로케이터 및 맞춤형 데이터 형식을 포함하여 여러 구성을 가정할 수 있으므로 다양한 드래그 앤 드롭 기능을 통합할 수 있는 적응 가능한 특성을 부여합니다.
setData()를 사용하여 데이터 패키지화하기
조작 가능한 컴포넌트에서 리셉터클로 정보를 전달하기 위해 다용도 `dataTransfer` 엔티티가 제공하는 `setData()` 함수의 실용적인 기능을 활용합니다. 이 함수를 사용하면 전송하려는 데이터를 캡슐화하고 클래스 또는 카테고리를 지정할 수 있습니다. 기본적인 예시는 다음과 같습니다:
element.addEventListener('dragstart', (event) => {
event.dataTransfer.setData('text/plain', 'Hello, world!');
});
“지정된 요소”라고 하는 객체를 이동하는 행위를 시작하면 “텍스트/일반”이라는 분류가 할당된 “setData()”로 지정된 패키지 내에 “Hello, world!” 메시지를 캡슐화해야 합니다.따라서 이 정보는 이동 이벤트에 연결되며, 이후 “드롭” 작업이라고 하는 릴리스 과정에서 의도된 수신자가 획득할 수 있습니다.
getData()로 데이터 검색
드롭 가능한 요소에 연결된 이벤트 리스너를 통해 전송된 정보에 접근하기 위해 해당 이벤트 리스너 내에 있는 getData() 함수를 활용할 수 있습니다.
element.addEventListener('drop', (event) => {
const transferredData = event.dataTransfer.getData('text/plain');
console.log(`Received data: ${transferredData}`);
});
앞서 언급한 코드는 setData() 함수에 의해 미리 결정된 동일한 데이터 분류, 즉 텍스트/일반의 정보를 추출합니다. 따라서 드롭 가능한 컴포넌트의 환경 바로 근처에서 전달된 데이터를 조작하거나 검사할 수 있습니다.
드래그 앤 드롭 인터페이스 사용 사례
웹 애플리케이션에 드래그 앤 드롭 기능을 통합하면 사용자 경험을 향상시킬 수 있는 잠재력이 크지만, 특정 애플리케이션에 적합한지 여부를 결정하기 위해서는 구현에 대해 신중하게 고려해야 합니다.
데스크톱 또는 파일 관리자에서 지정된 드롭 영역으로 직접 파일을 끌어다 놓으면 제출 프로세스가 간소화되어 기존 파일 업로드 방식에 익숙하지 않은 사용자도 보다 사용자 친화적이고 쉽게 접근할 수 있습니다.
예를 들어, 작업 목록, 음악 재생 목록 또는 시각적 전시회와 같이 객체 모음을 구성해야 하는 특정 애플리케이션에서, 최종 사용자는 한 항목을 파악하고 다른 지정된 위치로 옮기는 행위를 통해 수동 조작을 통해 이러한 요소를 정렬하는 데 이점을 발견할 수 있습니다.
대화형 대시보드는 사용자 친화적인 드래그 앤 드롭 기능을 통해 직관적인 데이터 시각화 및 보고 방법을 제공하며, 이를 통해 개인이 그래픽 요소와 표현을 적절하게 재구성하여 인터페이스를 개인화할 수 있습니다.
접근성을 염두에 두기
시각적으로 매력적인 끌어서 놓기 기능을 활용하면서 포용적인 사용자 환경을 만들려면 장애인을 포함한 모든 사용자의 접근성을 고려하는 것이 필수적입니다. 여기에는 보다 포괄적이고 공평한 인터페이스 디자인을 촉진하기 위해 키보드 기반 컨트롤과 같은 보조적인 상호 작용 수단을 통합하는 것이 포함될 수 있습니다.