728x90
HTML5의 드래그 앤 드롭은 웹 페이지로 다른 대상 객체를 끌어다 놓을 수 있는 기능을 제공한다
블로그에서 드래그 앤 드롭을 다룬적이 있으며 다음의 글을 참고하자
=> [HTML5] 드래그 앤 드롭 (Drag & Drop)

이전 글에서 간단한 데모를 다뤘었는데, 동일한 페이지에 있는 select 박스간 항목의 이동이었다
이번에는 웹 페이지 외부에 있는 파일(이미지파일, 텍스트 파일)을 웹 페이지로 드래그 해서 놓는 실습을 해 보도록 하자

우선 먼저 참고할 사항은, 브라우저간 일관되지 않은 결과가 나타난다는 것이다
http://caniuse.com/ 사이트에 따르면 드래그 앤 드롭은 IE와 오페라를 제외한 크롬,사파리,파이어폭스에서 동작한다고 되어 있다. 그리고 이번 데모에서 사용할 HTML5 File API 역시 크롬,사파리,파이어폭스에서 동작한다고 되어 있다.

그러나 막상 테스트를 해 보면 조금씩 다른 결과를 보여주어 당혹스럽게 한다
HTML5 자체가 브라우저마다 조금씩 다르게 지원하거나 일부가 누락된 경우가 있다고는 하지만
드래그 앤 드롭에 있어서는 더욱 일관되지 못함을 볼 수 있다

어쨋던 이 글에서 만든 데모는 파이어폭스에서 정상 동작하며 크롬에서 동작시키기 위해서는 특정 API를 제거해야 한다. 데모를 보여준 후 추가로 언급하겠다

실습, 외부파일을 웹페이지로 끌어다 놓기
웹 페이지이 외부 즉 데스크탑에 있는 이미지 파일 혹은 텍스트 파일을 웹 페이지의 DIV 영역으로 끌어다 놓는 데모를 제작해 보자

드래그 앤 드롭에 대한 기술적 요소는 이전에 작성한 강좌를 참고하도록 하며,
추가로 사용된 HTML5 File API 는 데모를 통해 알아보도록 하자

데모를 간단히 설명하면 이미지를 드롭했을 때에는 페이지에 이미지가 표시되며 텍스트파일을 드롭했을 때에는 텍스트파일의 내용이 페이지에 표시되도록 한다


바로 전체 소스코드를 보도록 하자
<!DOCTYPE html>
<html>
  <head> 
  <style>
    #dropbox {
    margin: auto;
    width: 300px;
    height: 300px;
    border: 5px solid #3C2F2E;
    -moz-border-radius: 15px;
    margin-top: 30px;
  }
  </style>
  </head> 
  <body>         
    <div id="dropbox" ondragenter="onDragEnter(event)"  ondragover="onDragOver(event)"
       ondrop="onDrop(event)">           
    </div>           
  </body>
</html>
<script type="text/javascript">               
  var dropBox = document.getElementById("dropbox");         
  var dropImage = document.createElement("img");  
         
  function onDragEnter(event){   
      if (event.dataTransfer.dropEffect == "move")
        event.preventDefault();                   
    }   
  function onDragOver(event){
    if (event.dataTransfer.dropEffect == "move") {
      event.preventDefault();     
  }                 
  function onDrop(event){                               
    var file = event.dataTransfer.files[0];     
          
    var imageType = /image.*/;
    var textType = /text.*/;
    var isImage;
   
    if(file.type.match(imageType)){
      isImage = true;
    }
    else if(file.type.match(textType)){
      isImage = false;
    }
            
    var reader = new FileReader();   
   
    reader.onload = (function(aFile){return function(e) {        
        var result = e.target.result
        if(isImage){
          dropImage.src = result;                                                                           
          dropBox.appendChild(dropImage)
         }
         else{
           dropBox.innerHTML = result;
         }        
        };
      })(file);
     
    if(isImage){ reader.readAsDataURL(file); }
    else { reader.readAsText(file,"EUC-KR"); }
   
    event.stopPropagation();
    event.preventDefault();
  }                     
 
  dropImage.addEventListener("load", function(e) {
    //이미지 로딩 시 추가 처리할 로직 기입(사이즈 조절 등)           
  }, true);         
</script>


드롭 이벤트에서(onDrop)에서 외부 파일을 드롭했을 때 그 정보를 취득하기 위한
다음의 코드가 사용되며
  event.dataTransfer.files[0],

이렇게 전달된 파일 데이터를 읽기 위해 FileReader(File API 중 파일을 읽기 위한 객체)를 사용했다
FileReader의 Load 이벤트에서 드롭으로 전달된 파일정보를 읽어 들여 이미지 혹은 텍스트를 DIV 에 출력하는 것이다
> 이미지 읽기: reader.readAsDataURL(file);
> 텍스트 읽기: reader.readAsText(file,"EUC-KR");

아래 그림은 데모를 실행한 결과모습인데, 텍스트 파일과 이미지 파일을 드롭한 후 또 다른 이미지 파일을 드롭하기 위해 웹페이지로 옮기는 모습니다. 전체 코드이기에 직접 실행해 보기 바란다.
소스나 기능이 최적화 되지는 않았지만 응용을 위한 기본자료로써는 충분할 것이다



우선 이 데모는 파이어폭스에서만 정상 동작한다
만일 크롬에서 동작시키려면 event.dataTransfer.dropEffect 속성을 사용해서는 안된다
아마도 크롬 브라우저는 dataTransfer 객체의 dropEffect 속성이 구현되지 않았나 보다

즉 onDragEnter 와 onDragOver 이벤트코드에서 if (event.dataTransfer.dropEffect == "move")
부분을 제거하거나 아래와 같이 두 이벤트를 무시하면 된다
ondragenter="return false;"
ondragover="return false;"

이로써 파이어폭스와 크롬에서 잘 동작하지만 사파리와 오페라는 여전히 동작하지 않는다
주제와 벗어나는 말이지만, HTML5의 드래그앤드롭과 File API 는 아직 실서비스에 적용하기에는 무리가 있지 않나 싶다

외부파일의 드래그 드롭은 아래 사이트를 참조하면 보다 유익한 정보를 얻을 수 있다
http://demos.hacks.mozilla.org/openweb/imageUploader/ (파이어폭스에서 실행해야 함)

http://hacks.mozilla.or.kr/2010/07/an-html5-offline-image-editor-and-uploader-application/

https://www.ibm.com/developerworks/mydeveloperworks/blogs/bobleah/entry/html5_code_example_of_file_api_drag_drop_hard_drive_files_to_a_webpage28?ca=dgr-jw22BobHTML5Tip1&lang=en

'모바일 > HTML5' 카테고리의 다른 글

Visual Studio 에서 HTML5 템플릿 만들기  (0) 2010.09.28
MS의 고뇌?, 실버라이트와 HTML5  (0) 2010.09.16
[HTML5] LocalStorage 와 크로스브라우저  (2) 2010.09.14
[CSS3] Animation  (0) 2010.09.13
[CSS3] Transform  (2) 2010.09.10