그럼에도 불구하고

👨‍💻

Drag & Drop 이용하여 이미지 올리기 본문

JavaScript/Function implementation

Drag & Drop 이용하여 이미지 올리기

zenghyun 2023. 1. 26. 16:09

Drag & Drop 이용하여 이미지를 올려보자

 

 

 

HTML

 

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <link rel="stylesheet" href="./style.css">
  <script src="main2.js" defer></script>
</head>
<body>
  <div class="file-zone">
    이미지를 올려주세요
  </div>

  <div class="file-preview-area">
    <h1>업로드한 이미지</h1>
    <div class="image-list">

    </div>
  </div>
</body>
</html>

 

 

CSS

더보기
body {
  display: block;
  overflow: scroll;
  width: 100%;
  height: 100vh;
}

.file-zone {
  background-color: rgba(0, 0, 0, 0.1);
  box-sizing: border-box;
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
  height: calc(100% - 400px);
  transition: 0.1s all ease-out;
}

.file-zone.on {
  background-color: rgba(97, 131, 209, 0.9);
}

.file-preview-area {
  width: 100%;
  min-height: 400px;
  background-color: rgba(0, 0, 0, 0.58);
  overflow: hidden;
}

.file-preview-area .image-list {
  display: grid;
  overflow: scroll;
  gap: 10px;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: 400px;
}

.file-preview-area .image-list>img {
  width: 100%;
  height: 100%;
  display: block;
  object-fit: cover;
}

 

 

JavaScript

 

const fileZone = document.querySelector('.file-zone');

const className = 'on';

fileZone.addEventListener('dragover', (event) => {
  event.preventDefault();
  fileZone.classList.add(className);
})

fileZone.addEventListener('dragleave', (event) => {
  event.preventDefault();
  fileZone.classList.remove(className);
})

fileZone.addEventListener('drop', (event) => {
  event.preventDefault();
  fileZone.classList.remove(className);

  const transferdFiles = event.dataTransfer.files;

  displayImages(transferdFiles);
})

function displayImages(transferdFiles) {
  const imageFileList = [];

  const fileNum = transferdFiles.length;

  for (let i = 0; i < fileNum; i++) {
    if (transferdFiles[i].type.match('image.*') === false) {
      return;
    }
    imageFileList.push(transferdFiles[i]);
  }

  const imagePreviewArea = document.querySelector('.image-list');

  for (let imageFile of imageFileList) {

    const fileReader = new FileReader();
    fileReader.readAsDataURL(imageFile);
    fileReader.addEventListener('load', (event) => {
      const image = new Image();
      image.src = event.target.result;

      imagePreviewArea.insertBefore(image, imagePreviewArea.firstChild);
    });
  }
}

 

 

 


 

 

const fileZone = document.querySelector('.file-zone');

const className = 'on';

fileZone.addEventListener('dragover', (event) => {
  event.preventDefault();
  fileZone.classList.add(className);
})

fileZone.addEventListener('dragleave', (event) => {
  event.preventDefault();
  fileZone.classList.remove(className);
})

 

on 이라는 클래스를 이용하여 이미지가 dragover과 dragleave 됐을 때의 시각적인 효과를 부여한다. 

 

 

 

※  dragover

 

 

※  dragleave 

 

 


 

# event.preventDefault()

 

event.preventDefault()를 사용하여 해당 이벤트의 기본동작을 실행하지 않게 만든다.

 

 

 

[Javascript] event.preventDefault() 와 event.stopPropagation()

event.preventDefault()와 event.stopPropagation()에 대해 알아보자 [ event.preventDefault() ] event 인터페이스의 preventDefault() 메서드는 어떤 이벤트를 명시적으로 처리하지 않은 경우, 해당 이벤트에 대한 사용자

despiteallthat.tistory.com

 

 

event.preventDefault()를 사용하지 않는 경우

 

 

이미지를 dragover, dragleave, drop 하게 되면 

 

 

 

자동적으로 내가 올린 이미지를 새로운 창으로 띄우게 된다. 이것을 preventDefault 메서드를 통해 막는 것이다.

 

 

 


 

 

fileZone.addEventListener('drop', (event) => {
  event.preventDefault();
  fileZone.classList.remove(className);

  const transferdFiles = event.dataTransfer.files;

  displayImages(transferdFiles);
})

 

transferdFileds 라는 변수는 drop 된 image 파일의 정보를 가져오기 위해 dataTransfer.files를 사용한다.

 


 

# event.dataTransfer.files

dataTransfer.files는 drag 작업을 할 때 사용한다. dataTransfer 객체의 파일 속성은 drag 해 온 작업의 파일 목록을 말하며, drag에 파일이 포함되어 있지 않으면 목록이 비어있게 된다. 

 

이 기능은 사용자의 데스크톱에서 브라우저로 파일을 드래그할 때 사용할 수 있다.

 

REF: https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer/files

 

DataTransfer.files - Web APIs | MDN

The files property of DataTransfer objects is a list of the files in the drag operation. If the operation includes no files, the list is empty.

developer.mozilla.org

 

drag & drop 기능을 사용할 경우 유용하게 사용할 수 있으니 꼭 알아두자 :) 

 

그후에 displayImages()라는 함수에 transferdFiles를 인자로 넘기게 된다. 

 

 

function displayImages(transferdFiles) {
  const imageFileList = [];

  const fileNum = transferdFiles.length;

  for (let i = 0; i < fileNum; i++) {
    if (transferdFiles[i].type.match('image.*') === false) {
      return;
    }
    imageFileList.push(transferdFiles[i]);
  }

  const imagePreviewArea = document.querySelector('.image-list');

  for (let imageFile of imageFileList) {

    const fileReader = new FileReader();
    fileReader.readAsDataURL(imageFile);
    fileReader.addEventListener('load', (event) => {
      const image = new Image();
      image.src = event.target.result;

      imagePreviewArea.insertBefore(image, imagePreviewArea.firstChild);
    });
  }
}

 

내가 drop 한 image를 받기 위하여 imageFileList라는 변수를 배열로 선언한다. 

 

const fileNum = transferdFiles.length;

  for (let i = 0; i < fileNum; i++) {
    if (transferdFiles[i].type.match('image.*') === false) {
      return;
    }
    imageFileList.push(transferdFiles[i]);
  }

 

받아온 file의 개수만큼 for문을 돌리고, 받아온 파일의 파일 양식이 image 파일일 때만 imageFileList에 저장한다.

 

 const imagePreviewArea = document.querySelector('.image-list');

  for (let imageFile of imageFileList) {

    const fileReader = new FileReader();
    fileReader.readAsDataURL(imageFile);
    fileReader.addEventListener('load', (event) => {
      const image = new Image();
      image.src = event.target.result;

      imagePreviewArea.insertBefore(image, imagePreviewArea.firstChild);
    });
  }
}

 

저장된 file 수만큼 다시 for문으로 반복하여 imageFile의 URL값으로 image의 경로를 생성해 준다. 

 

https://despiteallthat.tistory.com/92

 

[JavaScript] FileReader 객체에 대해 알아보자

FileReader란 무엇인가? [ FileReader란? ] FileReader란 type이 file인 input 태그 또는 API 요청과 같은 인터페이스를 통해 File 또는 Blob 객체를 편리하게 처리할 수 있는 방법을 제공하는 객체이다. abort, load, e

despiteallthat.tistory.com

 

.image-list 클래스를 가진 div 태그에 (imagePreviewArea) image를 넣은 순서대로 삽입해 준다. 

 

여기서 .insertBefore()메서드를 이용하면 참조된 노드 앞에 특정 부모 노드의 자식 노드를 삽입할 수 있다. 

 

즉 image 태그 ( 자식 노드 )를 imagePreviewArea ( 부모 노드 )에 삽입하는 것이다. 

 

 

REF: https://developer.mozilla.org/ko/docs/Web/API/Node/insertBefore 

 

Node.insertBefore() - Web API | MDN

Node.insertBefore() 메소드는 참조된 노드 앞에 특정 부모 노드의 자식 노드를 삽입합니다. 만약 주어진 자식 노드가 document에 존재하는 노드를 참조한다면, insertBefore() 가 자식 노드를 현재 위치에서

developer.mozilla.org

 

'JavaScript > Function implementation' 카테고리의 다른 글

배경색 무작위 조작하기  (0) 2023.02.02
숫자 뽑기 게임  (0) 2023.01.31
"selectstart" 글자 돋보기 만들기  (0) 2023.01.10
아날로그 시계 만들기  (0) 2023.01.07
mousemove 이벤트로 색 변환하기  (0) 2023.01.06
Comments