본문 바로가기
[Elice] FE Study

[JS] 이미지 파일 업로드

by 지공A 2024. 1. 8.

이미지 파일 업로드 실습 강의을 Line by Line 로 이해하기 위해 작성

 

포스트를 추가하는 아래 modal 화면에서 이미지 파일을

업로드하는 기능을 구현

 

이미지 파일 업로드 실습 코드 :

더보기
import close from './assets/close_icon.svg';
import media from './assets/media_icon.svg';
import arrow from './assets/arrow_back_icon.svg';

const modal = `
                <div class="modal__close">
                  <img
                  width="22px"
                  height="22px"
                  src=${close}
                  alt="close_icon_logo"
                  />
                </div>
                <div class="modal__card">
                  <div class="modal__header">
                    <div class="modal__back">
                      <img width="32px" height="24px" src=${arrow} alt="arrow_back_icon" />
                    </div>
                    <h2>새 게시물 만들기</h2>
                    <p>공유하기</p>
                  </div>
                  <div class="modal__main">
                    <img src=${media} alt="media_icon" />
                    <h3>사진과 동영상을 업로드 해보세요.</h3>
                    <label for="file">
                      <p>컴퓨터에서 선택</p>
                    </label>
                    <input type="file" name="file" id="file" />
                  </div>
                </div>
              `;

function createPost(img) {
  // 업로드한 이미지를 가져와 해당 이미지의 포스트 추가 모달 창이 열린다
  return `
          <div class="modal__post">
            <img width="478px" height="478px" src=${img} alt="image" />
            <div class="modal__write">
              <textarea placeholder="문구 입력..." autofocus></textarea>
            </div>
          </div>
        `;
}

document.querySelector('#add-post').addEventListener('click', createModal);

function createModal() {
  const modalEl = document.createElement('div');
  modalEl.setAttribute('class', 'modal__layout');
  modalEl.innerHTML = modal;

  document.querySelector('body').prepend(modalEl);

  document
    .querySelector('.modal__close')
    .addEventListener('click', function () {
      document.querySelector('body').removeChild(modalEl);
    });

  // 지시사항에 맞춰 코드를 작성해주세요.
  const fileEl = document.querySelector('#file');

  fileEl.addEventListener('input', function () {
    const reader = new FileReader();
    reader.readAsDataURL(fileEl.files[0]);
    reader.onload = function () {
      const imageBase64 = reader.result;

      document
        .querySelector('.modal__card')
        .setAttribute('class', 'modal__card write--post');

      document
        .querySelector('.modal__main')
        .setAttribute('class', 'modal__main write--post');

      const backBtn = document.querySelector('.modal__back > img');
      const shareBtn = document.querySelector('.modal__header > p');

      backBtn.style.visibility = 'visible';
      shareBtn.style.visibility = 'visible';

      document.querySelector('.modal__main').innerHTML =
        createPost(imageBase64);

      backBtn.addEventListener('click', function () {
        document.body.removeChild(modalEl);
        createModal();
      });
    };

    reader.onerror = function () {
      alert('Error', error);
      document.body.removeChild(modalEl);
    };
  });
}

 1. fileEl에 저장된 값 : <input type="file" name="file" id="file" />

const fileEl = document.querySelector('#file');

 

 2. 이미지를 추가했을 때의 이벤트 리스너 등록

fileEl.addEventListener('input', function () {
    const reader = new FileReader();

    reader.readAsDataURL(fileEl.files[0]);
    reader.onload = function () {
        ...
    };
    reader.onerror = function () {
    	...
    };
    ...
  • const reader = new FileReader() : 파일을 읽기 위한 FileReader 객체 생성 
  • reader.readAsDataURL(fileEl.files[0]) : 
    • input 태그가 type="file"이면, input 요소에 files로 접근하면 사용자가 선택해서 읽은 파일들에 대한 정보를 얻어낼 수 있습니다.
    • 하나의 파일만 input 할 예정이기 때문에 첫 번째 파일인 files[0]에 접근합니다.
  • reader.readAsDataURL(fileEl.files[0]) : 
    • FileReader 객체에서 제공하는 readAsDataURL 메서드를 이용해 input 태그를 이용해 업로드된 파일을 넘겨줄 수 있습니다.
    • readAsDataURL 메서드는 파일의 내용을 Base64로 인코딩하여 데이터 URL로 반환합니다.
    • FileReader readAsDataURL 메서드를 실행한 후 정상적으로 파일을 읽었을 때는 onload 메서드에 함수를 넣어 코드 흐름을 제어할 수 있습니다.
    • 정상적으로 파일을 읽었다면, result 메서드를 사용하여 읽은 데이터 URL에 접근할 수 있습니다.
    • 만약 파일을 읽다가 에러가 발생한다면 onerror 메서드에 함수를 넣어 코드 흐름을 제어합니다.

 

3. FileReader.onload() 작성

 reader.onload = function () {
      const imageBase64 = reader.result;

      ...
      /* css style */
      ...
      
      document.querySelector('.modal__main').innerHTML =
        createPost(imageBase64);
    };
  • reader.result : 이미지 로드가 완료되면, result 프로퍼티를 통해 접근 할 수 있습니다.
  • createPost 함수의 인자는 <img width="478px" height="478px" src=${img} alt="image" /> 에서 사용하므로 저장된 result 값이 img 요소의 src 값으로 전달됩니다.

결과 화면 : 


2024.01.08 Elice week - 02

'[Elice] FE Study' 카테고리의 다른 글

[JS] FileReader로 이미지 파일 업로드하기  (0) 2024.01.08
[CSS] CSS Animation  (0) 2024.01.08
[JS] Dom, Event  (0) 2024.01.06