changed 4 years ago
Linked with GitHub

HTML drag and drop API

유저는 draggable element를 마우스로 선택하고, drag하여 droppable element에 drop한다.

Drag Event

  • drag (ondrag) : 드래그할 때 발생
  • dragend (ondragend)
  • dragexit
  • dragenter : 유효한 drag target에 진입했을 경우
  • dragleave : 유효한 drag target을 떠났을 경우
  • dragover : 적절한 드롭 대상위로 지나갈 때 발생
    • 매 100 밀리세컨마다 발생한다.
  • dragstart
  • drop

Interface

  • interface : DragEvent, DataTransfer, DataTransferItem, DataTransferItemList

  • DragEvent : constructor와 DataTransfer 개체인 dataTransfer 프로퍼티를 갖는다.

  • DataTransfer 객체 : drag event state를 갖는다. 각 drag event는 dragTransfer 프로퍼티를 갖고 있다.

    • 프로퍼티
      • items : DataTransferItem 객체의 list이다.
      • effectAllowed : 모든 가능한 operation의 타입 - none, copy, copyLink, copyMove, link, linkMove, move, all, uninitialized 중의 하나이다.
      • dropEffect : 현재 선택된 DnD operation의 타입을 얻거나, 새로운 타입으로 operation을 설정한다. none, copy, link, move 중 하나여야 한다.
      • files
      • types : dragstart event에서 결정되는 포맷의 string 배열이다.
    • 메서드
      • clearData()
      • getData()
      • setData()
      • setDragImage()
  • DataTransferItem 객체 : 하나의 Drag itemdlek.

    • kind property : string or file
    • type property : data item의 MIME type
    • drag item의 Data를 get하는 메서드를 갖는다.
  • DataTransferItemList 객체 : list of DataTransferItem 객체

    • 메서드 : drag item 추가, 삭제, 전체 drag items 삭제
  • DataTransfer와 DataTransferItem 인터페이스의 차이

    • DataTransfer : 동기적 getData() 메서드 : drag item의 데이타에 접근
    • DataTransferItem : 비동기 getAsString() 메서드
  • DragTransferItem와 DragTransferItemList 인터페이스는 브라우저의 지원 범위가 제한된다.

draggable attribute

  • draggable 이 true일 경우, 해당 엘리먼트를 drag할 수 있다고 판단한다.
  • 디폴트는 auto : text selection, image, link만 drag할 수 있다.
<p draggable="true" ondragstart="event.dataTransfer.setData('text/plain', 'This text may be dragged')">
  This text <strong>may</strong> be dragged.
</p>

Drag Effects

dropEffect 프로퍼티는 유저에게 drag and drop 중에 어떠한 일이 일어나는지를 유저에게 피드백을 주는 역할을 한다. 주로, drag를 하는 동안 어떠한 cursor가 보일 것인지를 결정한다.

여기에 세 operation이 있고, 이를 조합한 것들도 존재한다.

  • copy : data가 drop location으로 카피될 것임을 알린다. => + 커서
  • move : drag되는 데이타가 움직일 것이다.
  • link : source와 drop 위치 간의 관계가 있을 것이다. => link 커서(약간 공유할 때 아이콘)

dragstart event listener 안에서 effectAllowed 프로퍼티에 어떠한 operation이 허용되는지를 지정할 수 있다.

  • dropEffect

drag operation이 일어나는 동안, dragenterdragover events는 effectAllowed 프로퍼티를 보고 어떠한 operation이 허용되는지를 확인한다. dropEffect 프로퍼티도 이 이벤트 중 하나에 지정되어야 한다.

dropEffect에 허용되는 operation은 none, copy, move, link 중 하나이다.

Drop Target 지정하기

dragenterdragover 이벤트에서 유효한 drop target인지를 지정한다. 대부분의 웹 페이지에서는 data를 drop하기에 적절하지 않으므로, 이 이벤트들의 디폴트 핸들러는 drop을 허용하지 않는 것이다.

따라서, drop을 허용하고 싶을 때는 dragenterdragover 이벤트 둘 다에 디폴트 핸들링을 취소해야 한다. defaul handling을 취소하는 방법은

  1. 이벤트 핸들러에서 false를 리턴하기 or
  2. event의 preventDefault 메서드를 호출하기

dragenter와 dragover 이벤트 둘 다에 preventDefault를 호출함으로써, 그 위치에 drop이 허용된다.

Drop

마우스가 drop target에서 놓아지면, drop 이벤트가 발생한다.

웹페이지에서 drop 이벤트 핸들러에 반드시 preventDefault 메서드를 호출해야 drop 이벤트를 받아들인다는 의미가 되고, 브라우저도 default handling을 수행하지 않게 된다. 예를 들어, firefox는 링크를 드래그하면, 링크를 열게 되는데, 이 디폴트 핸들링을 취소해야 한다.

Finishing a Drag

drag가 끝나게 되면, dragend 이벤트가 source element(dragstart가 시작된 element)에 발생하게 된다.
drop이 성공했던, 실패했던 이 이벤트는 발생한다. 실패와 성공 여부는 dropEffect 프로퍼티로 알 수 있다.

  • 여기서 dropEffect 프로퍼티가 none이면, drag는 취소되었음을 알 수 있다.
  • 만약 drag가 성공적이었다면, 다른 operation이 set되어있을 것이다.

출처

Select a repo