게시글

5만명이 선택한 평균 별점 4.9의 제로초 프로그래밍 강좌! 로드맵만 따라오면 됩니다! 클릭
강좌13 - HTML&DOM - 7년 전 등록

드래그 드롭 API

안녕하세요. 이번 시간에는 드래그 드롭 api에 대해 알아보겠습니다. 지난 시간에 배운 File API와 같이 사용하면 좋습니다. 보통 파일을 특정 구역에 드롭해서 업로드하기 때문이죠.

우선 HTML 태그를 드래그하는 방법부터 알아보죠. 보통 태그들은 드래그할 수 없습니다. 하지만 태그의 속성으로 draggable="true"를 주면 그제서야 드래그가 되기 시작합니다. 그리고 드롭할 구역이 필요하겠죠? 드롭할 구역에는 JS로 ondragoverondrop 이벤트 핸들러를 연결해주어야 합니다.

위와 같이 드래그 후 드롭할 수 있습니다. 그 와중에 데이터를 전달할 수 있습니다. JS 부분을 보시면

document.getElementById('drag').ondragstart = function() {
  e.dataTransfer.setData('data', this.innerHTML); // 드래그해보세요 문자열 전달
};

document.getElementById('drop').ondragover = function(e) {
  e.preventDefault(); // 필수 이 부분이 없으면 ondrop 이벤트가 발생하지 않습니다.
};
document.getElementById('drop').ondrop = function() {
  alert(e.dataTransfer.getData('data')); // 데이터를 가져옵니다.
};

dragstart 이벤트핸들러에서 e.dataTransfer.setData로 전달할 데이터를 지정해줍니다. setData는 키-값 형식으로 저장하기 때문에, 키만 다르면 여러 개의 데이터를 저장할 수 있습니다. dragover이벤트에서는 e.preventDefault()로 drop 이벤트가 호출될 수 있게 해주고요. drop 이벤트에서 e.dataTransfer.getData로 데이터를 받을 수 있습니다.

이번에는 파일을 직접 드롭해보죠. 아무 파일이나 끌어서 아래에 넣어보세요.

var drop = document.getElementById('drop');
drop.ondragover = function(e) {
  e.preventDefault(); // 이 부분이 없으면 ondrop 이벤트가 발생하지 않습니다.
};
drop.ondrop = function(e) {
  e.preventDefault(); // 이 부분이 없으면 파일을 브라우저 실행해버립니다.
  var data = e.dataTransfer;
  if (data.items) { // DataTransferItemList 객체 사용
    for (var i = 0; i < data.items.length; i++) { // DataTransferItem 객체 사용
      if (data.items[i].kind == "file") { // 아이템 종류가 파일이면
        var file = data.items[i].getAsFile(); // File API 사용
        alert(file.name);
      }
    }
  } else { // File API 사용
    for (var i = 0; i < data.files.length; i++) {
      alert(data.files[i].name);
    }
  }
};

아까와는 다르게 e.dataTransfer.itemse.dataTransfer.files를 사용합니다. files 객체는 File API이기 때문에 그 강좌 에 나오는 대로 하면 드롭한 파일을 처리할 수 있습니다. 하지만 dataTransfer 객체에는 DataTransferItemList라는 특수한 객체가 있습니다. 구형 브라우저에서는 files 객체가 작동하지 않기 때문에 어쩔 수 없이 items 객체를 사용해야 합니다. 참고로 여러 개의 파일을 드롭하면 모두 받아지는데요. 그래서 위의 코드에서 for 문으로 DataTransferItemList를 DataTransferItem으로 나눠준 겁니다.

DataTransferItem 객체 안에는 kind와 type 속성이 있는데요. type은 png파일이면 'image/png' 이렇게 파일의 속성을 알려주고요. kind는 드롭한 것이 파일인지(file) 문자열인지(string) 알려줍니다. 위의 코드에서는 kind가 file일 때 getAsFile 메소드를 호출하라고 되어있습니다. 이 메소드를 호출하면 다시 File API에 해당하는 파일 객체를 반환합니다.

그렇다면 File API를 쓰면 되지 왜 굳이 DataTransferItem 객체를 사용하는 걸까요? 아까도 말씀드렸다시피 파일 말고도 문자열도 드롭할 수 있습니다. 문자열을 드롭하게 되면 kind는 string, type은 text/*가 되고요. 데이터는 getAsString 메소드로 받을 수 있습니다.

data.items[i].getAsString(function(s) {
  console.log(s);
});

getAsFile과는 다르게 콜백 함수를 통해서 데이터를 받습니다. 문자열이 길 경우 등의 이유로 동기적으로 처리하기보다는 비동기적으로 처리하기로 한 것 같습니다.

드래그 앤 드롭의 단점은 모바일에서는 이 API를 사용할 수 없다는 겁니다. 하지만 모바일에서는 거의 드래그 앤 드롭을 쓸 일이 없기 때문에 그렇게 중요한 문제는 아닌 것 같습니다.

드래그 앤 드롭도 별 거 아니죠? 특히 File API와 같이 사용하면 쉽게 이미지 업로드를 할 수 있습니다. 다음 시간에는 이미지를 폼으로 업로드할 수 있는 FormData 객체에 대해 알아봅시다!

조회수:
0
목록
투표로 게시글에 관해 피드백을 해주시면 게시글 수정 시 반영됩니다. 오류가 있다면 어떤 부분에 오류가 있는지도 알려주세요! 잘못된 정보가 퍼져나가지 않도록 도와주세요.
Copyright 2016- . 무단 전재 및 재배포 금지. 출처 표기 시 인용 가능.
5만명이 선택한 평균 별점 4.9의 제로초 프로그래밍 강좌! 로드맵만 따라오면 됩니다! 클릭

댓글

1개의 댓글이 있습니다.
7년 전
좋은 글 감사합니다. 요즘 NodeJs 관심이 많은데, 도움이 되는 유용한 글들이 많은 것 같습니다. 계속 좋은 글 부탁드려요.