[HTML / CSS] HTML 드래그 앤 드롭 API 알아보기

SEONDY·2024년 11월 24일

HTML / CSS

목록 보기
3/3
post-thumbnail

[HTML / CSS] HTML 드래그 앤 드롭 API 알아보기

1. HTML 드래그 앤 드롭 API

  • 이 기능을 이용해 draggable 요소를 마우스로 선택해 droppable 요소로 드래그하고, 마우스 버튼에서 손을 뗌으로써 요소를 드롭할 수 있다.
    드래그하는 동안, draggable 요소는 반투명한 채로 마우스 포인터를 따라다닌다.

드래그 이벤트

  • HTML 드래그 앤 드롭은, DOM event modeldrag eventsmouse events로부터 상속받는다.
    보통 드래그는 draggable 요소를 마우스로 선택하고, 마우스 포인터를 droppable 요소로 가져가 마우스 버튼을 떼는 것으로 이루진다.
    문서에서 각 드래그 이벤트에 대해 확인할 수 있다.

인터페이스

  • HTML 드래그와 드롭 인터페이스는 DragEvent, DataTransfer, DataTransferItem, DataTransferItemList이다.
  • DataTransfer 객체는 드래그 형태, 드래그 데이터(하나 이상의 아이템), 각 드래그 아이템의 종류와 같은 드래그 이벤트 상태를 담고 있다.
    또한, 드래그 데이터에 아이템을 추가하거나 제거하는 메소드를 가지고 있다.
  • DragEventDataTransfer 인터페이스만 있으면 어플리케이션에 HTML 드래그 앤 드롭 기능을 추가할 수 있다.
  • DataTransferDataTransferItem의 목록인 items 프로퍼티를 가지고 있다.
  • DataTransferItem은 하나의 드래그 아이템을 나타내고, 각 아이템은 데이터의 종류를 나타내는 kind 프로퍼티데이터 아이템의 종류를 나타내는 type 프로퍼티를 가진다.
    DataTransferItem은, 드래그 아이템의 데이터를 가져오는 메소드를 제공한다.
  • DataTransferItemList 객체는 DataTransferItem의 리스트이다.
    드래그 아이템을 리스트에 추가하거나, 리스트에서 아이템을 삭제하거나, 모든 드래그 아이템을 리스트에서 삭제하는 메소드를 가진다.
  • DataTransferDataTransferItem 주요 차이점
    • DataTransfer는, 드래그 항목의 데이터에 액세스하기 위해 동기 메소드 getData()를 사용함
    • DataTransferItem은, 비동기 메소드 getAsString() 을 사용함

드래그 앤 드롭 기본적인 방법

1. 어떤 것이 draggable인지 확인하기

  • 하나의 요소를 draggable로 만들기 위해서는 draggableondragstart 전역 이벤트 핸들러를 추가해야 한다.

    <script>
    function dragstart_handler(ev) {
      // 데이터 전달 객체에 대상 요소의 id를 추가합니다.
      ev.dataTransfer.setData("text/plain", ev.target.id);
    }
    
    window.addEventListener("DOMContentLoaded", () => {
      // id를 통해 element를 가져옵니다.
      const element = document.getElementById("p1");
      // 'dragstart' 이벤트 리스터를 추가합니다.
      element.addEventListener("dragstart", dragstart_handler);
    });
    </script>
    
    <p id="p1" draggable="true">This element is draggable.</p>

2. 드래그 데이터 정의하기

  • 드래그할 때 자유롭게 데이터 아이템을 포함할 수 있다.
  • 각 drag event는, 이벤트 데이터를 가지고 있는 dataTransfer를 가진다. (드래그 데이터를 관리하는 메소드를 가짐)
    setData()는, 아이템을 드래그 데이터에 추가할 때 사용한다.
    function dragstart_handler(ev) {
        // 드래그 데이터 추가 (setData)
        ev.dataTransfer.setData("text/plain", ev.target.id);
        ev.dataTransfer.setData("text/html", "<p>Example paragraph</p>");
        ev.dataTransfer.setData("text/uri-list", "http://developer.mozilla.org");
    }

3. 드래그 이미지 정의하기

  • 브라우저는 드래그하는 동안, 마우스 포인터 옆에 나타나는 이미지를 기본적으로 제공한다.
    다른 이미지 사용을 원한다면, setDragImage()를 사용할 수 있다. (변경하지 않으면 기본 이미지 사용)
    function dragstart_handler(ev) {
        // 드래그 이미지로 사용할 이미지
        var img = new Image();
        img.src = "example.gif";
        ev.dataTransfer.setDragImage(img, 10, 10);
    }

4. 드래그 효과 정의하기

  • dropEffect 프로퍼티는, 드래그 앤 드롭 도중에 사용자에게 피드백을 제공하기 위해 사용한다.
    드래그 하는 동안 어떤 마우스 포인터를 보여줄 지 결정
    마우스 포인터를 대상 드롭 요소에 올려놓으면, 드래그 효과에 적합한 마우스 포인터를 보여준다.
  • 효과
    • copy : 현재 위치에서 드롭하는 위치로 데이터가 복사될 것을 암시
    • move : 현재 위치에서 드롭하는 위치로 데이터가 이동할 것을 암시
    • link : 드래그하는 위치와 드롭하는 위치 간의 일종의 관계나 연결이 맺어진다는 것을 암시

5. 드롭 지역 정의하기

  • 기본적으로 브라우저는 HTML 요소에 뭔가를 드롭했을 때 아무 일도 일어나지 않도록 한다.
    특정 요소를 droppable로 만들기 위해서는 해당 요소가 ondragoverondrop 이벤트 핸들러 속성을 가져야 한다.
    각 핸들러는 preventDefault()를 호출해 추가적인 이벤트가 일어나지 않도록 한다.

    <script>
    function dragover_handler(ev) {
      ev.preventDefault();
      // dropEffect를 move로 설정
      ev.dataTransfer.dropEffect = "move";
    }
    function drop_handler(ev) {
      ev.preventDefault();
      // 대상의 id를 가져와 대상 DOM에 움직인 요소를 추가
      const data = ev.dataTransfer.getData("text/plain");
      ev.target.appendChild(document.getElementById(data));
    }
    </script>
    
    <p
    id="target"
    ondrop="drop_handler(event)"
    ondragover="dragover_handler(event)">
      Drop Zone
    </p>

6. 드롭 효과 다루기

  • drop 이벤트 핸들러는 자유롭게 드래그 데이터를 가공할 수 있다.
    보통, 가공을 위해 getData()를 사용한다.
    dropEffect 값이나 보조키 상태에 따라 어플리케이션이 어떻게 동작할지를 결정할 수 있다.

    <script>
    function dragstart_handler(ev) {
      // 데이터 전달 객체에 대상 요소의 id를 추가
      ev.dataTransfer.setData("application/my-app", ev.target.id);
      ev.dataTransfer.dropEffect = "move";
    }
    function dragover_handler(ev) {
      ev.preventDefault();
      ev.dataTransfer.dropEffect = "move";
    }
    function drop_handler(ev) {
      ev.preventDefault();
      // 대상의 id를 가져와 이동한 대상 DOM 요소를 추가
      const data = ev.dataTransfer.getData("application/my-app");
      ev.target.appendChild(document.getElementById(data));
    }
    </script>
    
    <p id="p1" draggable="true" ondragstart="dragstart_handler(event)">
    	This element is draggable.
    </p>
    <div
    id="target"
    ondrop="drop_handler(event)"
    ondragover="dragover_handler(event)">
       Drop Zone
    </div>

7. 드래그가 끝나면

  • 드래그한 요소에 dragend 이벤트가 발생한다. (완료되거나 중간에 취소되어도 발생)
    dropEffect 프로퍼티를 확인해 드래그가 성공했는지 확인할 수 있다.

2. 드래그 앤 드롭 구현 예제

링크에 들어가면, 기능과 다양한 구현 예제를 볼 수 있다!
출처: https://inpa.tistory.com/entry/드래그-앤-드롭-Drag-Drop-기능

내용 정리

  • HTML, JS에서 드래그 앤 드롭은 이벤트 기반으로 작동함
    마우스 커서로 객체를 드래그해서 놓을 때까지 여러 단계의 이벤트가 순차적으로 발생하여 동작이 완료됨

  • HTML에서 요소가 드래그 이벤트가 발생할 수 있도록 해당 요소의 속성으로 draggable="true"의 값을 줌

    • 태그 중, 디폴트로 draggable한 요소가 있음 (<a>)
  • 이벤트 순서
    drop, dragover 이벤트는 필수로 사용해야 하는 이벤트!

    • dragstart : 사용자가 객체를 드래그하려고 시작할 때 발생
    • drag : 대상 객체를 드래그하면서 마우스 움직일 때 발생
    • dragenter : 마우스가 대상 객체의 위로 처음 진입할 때 발생
    • dragover : 드래그하면서 마우스가 대상 객체의 영역 위에 자리 잡고 있을 때 발생
    • drop : 드래그하던 객체를 놓는 장소에 위치한 객체에서 발생
      리스너는 드래그된 데이터를 가져와서 드롭 위치에 놓는 역할을 함
    • dragleave : 드래그가 끝나서 마우스가 대상 객체의 위를 벗어날 때 발생
    • dragend : 대상 객체를 드래그하다가 마우스 버튼을 놓는 순간 발생
  • drop 이벤트는 dragover와 함께 사용 (함께 사용해야 동작이 됨)
    드롭될 요소에 e.preventDefault()를 사용하지 않으면 정상적인 동작이 되지 않을 수 있음

  • DataTransfer 객체
    드래그 앤 드롭 이벤트를 위한 모든 이벤트 리스너 메소드는 DataTransfer 객체를 반환함.
    DataTransfer 객체는 드래그 앤 드롭 동작에 관한 정보를 가지고 있음!

  • 이 객체 내에서는 데이터를 저장 / 가져오기 / 삭제를 수행할 수 있는 메소드를 가지고 있음

    • event.dataTransfer.setData(format, data)
      첫 번째 매개변수 : 포맷 문자열 지정
      첫 번째 매개변수에 지정한 포맷과 일치하는 값을 두 번째 매개변수로 지정
      두 번째 매개변수는 문자열만 지정 가능
    • event.dataTransfer.getData(format)
      첫 번째 매개변수에 지정한 포맷의 전송 데이터 반환
      지정된 포맷의 데이터가 지정되어 있지 않으면 공백 문자열 반환
    • event.dataTransfer.clearData() / event.dataTransfer.clearData(format)
      데이터 전송용으로 지정된 데이터를 모두 제거
      첫 번째 매개변수로 포맷 문자열을 지정하면 형식과 일치하는 데이터만을 제거
    • event.dataTransfer.types
      dragstart 발생 시 DOM 목록에 있는 data format을 설정하며 setData 함수 호출할 때 지정되는 format 문자열을 배열 형식으로 얻을 수 있음


참고 사이트

0개의 댓글