javascript로 이미지 업로드 및 미리보기 기능 구현하는 방법

이번에 간단한 프로젝트를 기획하면서 사진 업로드와 미리보기 기능을 구현하게 되었다. 처음에는 쉬울거라고 생각했지만 막상 하려고 하니 계속 막혔다. 무엇보다 시간을 잡아먹었던건 사진 10장 초과시 업로드를 불가능하게 만드는 것을 구현하는 것이였다. 이 과정에서 IT커뮤니티 사이트 OKKY에 질문을 많이 했었다. 약 2일 동안 이것만 한거 같다.

 

이미지 업로드

HTML

<input type="file" id="real-input" class="image_inputType_file" accept="img/*" required multiple>
<button class="browse-btn">사진업로드</botton>

input 태그에는 file형태와 image만 업로드할 수 있게 설정했다. 또한, 최대 10장까지 업로드할 수 있기 때문에 multiple 속성도 추가했다. 구현하고 싶은 것은 input 태그에 클릭해서 업로드하는 것이 아닌 button 태그를 클릭해서 업로드하고 싶었다. 왜냐하면 input 태그는 CSS 입히기가 쉽지 않기 때문이다. 따라서 CSS에는 input 태그는 display를 줘서 숨겨버리고 javascript에서 button을 클릭하면 input 태그를 통해 업로드하게끔 구현했다.

 

JavaScript

const browseBtn = document.querySelector('.browse-btn');
const realInput = document.querySelector('#real-input');

browseBtn.addEventListener('click',()=>{
	realInput.click();
});

이렇게 구현하니 button을 클릭하면 input 태그처럼 업로드 할 창이 나왔다. 이제 미리보기 기능을 구현할 차례다.

미리보기 기능

HTML

<h3>이미지 미리보기</h3>
<div id="imagePreview">
	<img id="img" />
</div>

미리보기 기능을 위해 미리보기 할 영역을 정하고 JavaScript에서 업로드할 사진의 수를 반복하여 append를 해서 나타나게 할 것이다.

 

JavaScript

function readInputFile(e){
    var sel_files = [];
    
    sel_files = [];
    $('#imagePreview').empty();
    
    var files = e.target.files;
    var fileArr = Array.prototype.slice.call(files);
    var index = 0;
    
    fileArr.forEach(function(f){
    	if(!f.type.match("image/.*")){
        	alert("이미지 확장자만 업로드 가능합니다.");
            return;
        };
        if(files.length < 11){
        	sel_files.push(f);
            var reader = new FileReader();
            reader.onload = function(e){
            	var html = `<a id=img_id_${index}><img src=${e.target.result} data-file=${f.name} /></a>`;
                $('imagePreview').append(html);
                index++;
            };
            reader.readAsDataURL(f);
        }
    })
    if(files.length > 11){
    	alert("최대 10장까지 업로드 할 수 있습니다.");
    }
}

$('#real-input').on('change',readInputFile);

input 태그에 jQuery 문법인 on을 통해 이벤트 바인딩을 했다. reqdInputFile함수로 가보면 sel_files에 배열로 줘서 이곳에 저장할 것이다. 이미지 미리보기 영역을 초기화하여 업로드 할 때마다 초기화한 후 다시 처리하게 했다.

 

 

e.target.files는 이벤트 객체인 e를 console에 찍어보면 type, target 등이 보였다. 그리고 MDN을 참고하여 taget에 files를 입력하니 fileList안에 배열형태로 파일에 대한 정보가 나온다. name, size, type 등 말이다. Array.prototype.slice.call(files)는 이 코드가 존재하는 함수의 매개변수로 넘어온 값을 Array(배열)로 변환하겠다는 것이다. 앞서 files는 배열형태를 띄우고 있기 때문에 가능하다.

 

fileArr는 배열로 되어있기 때문에 forEach를 쓸 수 있다. type.match를 통해 이미지 확장자만 업로드할 수 있도록 체크한다. 만약 이미지 확장자외에 다른 파일을 업로드 할 시 null이 반환된다.

 

files.lengh를 통해 11번째 업로드가 되면 업로드를 할 수 없게끔 구현했다. FileReader객체는 비동기적으로 파일을 읽기 위해 사용된다. 그 중 FileReader.onload는 load의 이벤트 핸들러로 읽기 동작이 성공적으로 완료 되었을 때마다 발생한다. readAsDataURL 메서드는 f를 읽어 오는 역할을 한다. 이 경우 업로드 된 파일의 정보를 읽는다.

 

 

이 글을 공유하기

댓글

Designed by JB FACTORY