프론트엔드-코드/Javascript

드래그 앤 드롭 파일 읽기

sdafdq 2023. 9. 27. 16:41
const dropZone = document.getElementById('file-box');
dropZone.addEventListener('dragover', e=>{
  e.stopPropagation();
  e.preventDefault();
});

dropZone.addEventListener('drop', e=>{
  e.stopPropagation();
  e.preventDefault();
  const files = e.dataTransfer.files;
  Array.from(files)
  .filter(file => file.type.match('image.*'))
  .forEach(file=>{
    const reader = new FileReader();
    reader.onload = e=>{
      const $img = document.createElement('img');
      $img.src = e.target.result;
      $img.title = file.name;
      document.getElementById('result').appendChild($img);
    }
    reader.readAsDataURL(file);
  })
});

 

 

 

 

const dropZone = document.getElementById('file-box');
dropZone.addEventListener('dragover', e=>{
  e.stopPropagation();
  e.preventDefault();
});

먼저 드롭존으로 쓸 file-box를 찾아준다.

dragover는 바깥에서 드래그 하면서 오다가 대상에 닿았을 때 이벤트가 발생한다.

그냥 드래그가 아니라, 무언갈 가지고 있어야 한다. 파일이든, 텍스트든.

 

dropZone.addEventListener('drop', e=>{
  e.stopPropagation();
  e.preventDefault();
  const files = e.dataTransfer.files;
  Array.from(files)
  .filter(file => file.type.match('image.*'))
  .forEach(file=>{
    const reader = new FileReader();
    reader.onload = e=>{
      const $img = document.createElement('img');
      $img.src = e.target.result;
      $img.title = file.name;
      document.getElementById('result').appendChild($img);
    }
    reader.readAsDataURL(file);
  })
});

드롭했을 때, 이벤트를 추가해 준다.

 

e.dataTransfer.files 해서 drop한 것을 파일 형식으로 files = 에다 넣어서 메모리에 넣어주고,

이미지만 거른 다음에,

reader를 생성해서

reader에 onload(파일을 다 읽어왔을 시) 이벤트를 추가시켜주고

이벤트 내용은

이미지태그를 생성해서 소스로 e.target.result를 넣어준다. 

파일에 대한 이벤트이니 타겟의 결과는 다 읽힌 파일이다.

 

이렇게 이벤트 추가시켜 주고,

 

reader.readAsDataURL(file)하면  파일이 다 읽혀 졌을 때 저 이벤트가 실행되는 것이다.

 

 

 

 

간소화 시킨 것

const dropZone = document.querySelector('#file-box');
const $result = document.querySelector('#result');

const reader = new FileReader();

dropZone.addEventListener('dragover', e=>{
  e.stopPropagation();
  e.preventDefault();
  console.log('in');
});


dropZone.addEventListener('drop', e=>{
  e.stopPropagation();
  e.preventDefault();
  const file = e.dataTransfer.files[0];
  console.log(file);
  reader.readAsDataURL(file);
})

reader.onload = (e)=>{
  const $img = document.createElement('img');
  $img.src = e.target.result;
  $result.appendChild($img);
};

 

간소화 시켜봤다.

dropZone은 파일 떨어뜨릴 위치,

result는 그냥 넣은 파일 태그로 해서 넣어줄 위치이다.

 

파일리더 생성하고

 

드래그오버 저기 기본이벤트 막아준 이유가, 원래 웹브라우저에 이미지 드래그 해서 넣으면 띄워줌. 그래서 그거 막은거. 또 버블링도 막았음. 안 막으면 전체가 드래그 영역이 될 수 있으니까.

 

드롭존에다 드롭 이벤트 추가 시킴.

이것도 버블링에 기본 이벤트 막고,

뭔가를 드롭해준걸 그걸 event.dataTransfer.files해서 파일 형태로 바꾸는 데, 0번째 인덱스를 가져옴.

왜 0번째로 가져오냐면, 드래그 해서 여러 파일 가져오거나 그러는 경우가 있는데, 파일 하나만 드래그 시킬거라 그렇다.

실제 서비스 하려면 예외처리라던지 files의 length를 읽어서 1보다 크면 뭐 거부한다음 알려준다던지 그런 처리를 해주면 될 듯 하다. 파일 종류도 file.type 가져와서 조건문 해주면 될 듯 하다.

 

reader 이벤트 추가시켜주는 거, 호이스팅이 되는 모양이다.

reader 이벤트 추가는 .addEventListner() 이렇게 하는게 아니라 리더.onload = 콜백함수

그냥 간단하게 img 태그 생성하고, 파일을 읽은 결과를 img 태그의 소스로 주고, $result에 자식으로 추가시켜줬다.

 

reader의 파일 읽는 종류도 여러가지 있는데, 이번에 사용한 것은 DataURL로써 읽는 것이다.

근데 읽는 종류가 뭐던간에, reader의 onload 이벤트는 데이터를 읽는 것을 끝마쳤을 경우 실행되는 이벤트 이므로 모두 적용된다.

'프론트엔드-코드 > Javascript' 카테고리의 다른 글

target과 currentTarget 차이  (0) 2023.10.10
XMLHttpRequest  (0) 2023.10.02
절대 위치, 상대위치 가져오기(스크롤 포함)  (0) 2023.09.27
태그 이름 알아오기  (0) 2023.09.27
html의 사용자 정의 속성  (0) 2023.09.27