input file 로 이미지 업로드를 하는 과정에서의 이미지 미리보기, 이미지 삭제 구현입니다.
input file multiple 은 아래 글을 참고하세요.
(준비중)
html
<div><input type="file" name="book_img" id="book_img" accept="image/*" required></div>
<div class="book-img-section" style="display:none;">
<img class="book-img-preview" height="350px" src="이미지경로"
onerror="this.src='https://cdn.pixabay.com/photo/2018/01/04/15/51/404-error-3060993__340.png';"/>
<button type="button" class="book-img-remove color_st05" onClick="">삭제</button>
</div>
input file 의 이름은 #_img
이고
각 class는 #-img-section
, #-img-preview
, #-img-remove
로 정하면 됩니다.#
에 원하는 네이밍을 부여하시면 됩니다. 이 부분이 아래에서 쓰일 tag 명칭이 됩니다.
src="이미지경로"
에 이미지가 있다면
src="이미지경로"
에 이미지가 없다면 #
을 넣어주세요.
이렇게 나오도록 javascript 를 작성합니다.
에러 처리는 onerror
로 해도 되고, js에서 이벤트 error
를 감지해서 처리해도 됩니다.
javascript
js 코드 부분 설명
input file binding
const book_img_tag = "book";
const book_img_reader = new FileReader();
const book_img_file = document.querySelector('#'+book_img_tag+'_img');
book_img_file.addEventListener('change', function(e){handleSelected(e, this, book_img_reader, book_img_tag)});
if(document.querySelector('.'+book_img_tag+'-img-preview').getAttribute('src') != "#") {
document.querySelector('.'+book_img_tag+'-img-section').style.display = "block";
book_img_file.required = false;
}
document.querySelector('.'+book_img_tag+'-img-remove').addEventListener("click", () => {
removeImage(book_img_file, book_img_tag);
});
img_tag는 위의 html에서 지정한 tag 명칭과 동일하게 주면 됩니다.
FileReader는 input file 로 입력되는 파일을 비동기적으로 확인할 수 있습니다.
예제에서는 FileReader로 업로드하려는 이미지를 미리보기에 바로 보여주는 방식으로 활용합니다.
💣예제에 관련된 내용만 설명했고, 자세한 설명은 아래 문서를 참고하세요.
developer.mozilla.org - FileReader
이제 input file 이 등록/변경 되었을 때 이벤트 처리를 해주면 됩니다.book_img_file.addEventListener('change', function(e){handleSelected(e, this, book_img_reader, book_img_tag)});
해당 부분이 이벤트 'change'
에 반응하는 handler를 지정하는 부분입니다.
여러 이미지를(여러 개의 input file) 업로드해야 하는 경우를 고려해서 reader
, tag
를 파라미터에 함께 넘깁니다.
삭제 버튼의 'click'
이벤트 발생 시 이미지를 삭제하는 부분도 추가합니다.
만약 error 체크까지 해야 한다면, 이벤트 'error'
에 핸들러를 추가해 코드를 작성하면 됩니다.
input file event listener
function addListeners(reader, fileTag) {
reader.addEventListener('load', function(e){handleEvent(e, reader, fileTag)});
}
function handleSelected(e, fileInput, reader, fileTag) {
const selectedFile = fileInput.files[0];
if (selectedFile) {
addListeners(reader, fileTag);
reader.readAsDataURL(selectedFile);
}
}
위에서 input file의 이벤트 발생 시, this
로 file 객체를 함께 넘겨주었습니다.fileInput.files[0]
로 선택한 파일을 가져올 수 있습니다.
선택된 파일이 있다면, reader에 리스너를 추가하고, readAsDataURL
로 파일의 내용을 읽어들입니다.
event handler
function handleEvent(event, reader, fileTag) {
if (event.type === "load") { // 이미지 로드 시 미리보기 경로 설정
document.querySelector('img.'+fileTag+'-img-preview').setAttribute('src', reader.result);
document.querySelector('.'+fileTag+'-img-section').style.display = "block";
}
}
실제 이벤트 처리 부분입니다.
미리보기 src
를 세팅하고 화면에 출력합니다.
file remove
function removeImage(fileInput, fileTag) {
document.querySelector('.'+fileTag+'-img-section').style.display = "none";
document.querySelector('.'+fileTag+'-img-preview').setAttribute('src', '#');
fileInput.value = '';
fileInput.required = true;
}
등록한 이미지와 미리보기를 제거하는 부분입니다.
js 전체 코드
<script>
/** START :: 이미지 관련 **/
(function() {
// 이벤트 핸들러
function handleEvent(event, reader, fileTag) {
if (event.type === "load") { // 이미지 로드 시 미리보기 경로 설정
document.querySelector('img.'+fileTag+'-img-preview').setAttribute('src', reader.result);
document.querySelector('.'+fileTag+'-img-section').style.display = "block";
}
}
// FileReader에 이벤트 핸들러 추가
function addListeners(reader, fileTag) {
// reader.addEventListener('loadstart', function(e){handleEvent(e, reader, fileTag)});
reader.addEventListener('load', function(e){handleEvent(e, reader, fileTag)});
// reader.addEventListener('loadend', function(e){handleEvent(e, reader, fileTag)});
// reader.addEventListener('progress', function(e){handleEvent(e, reader, fileTag)});
// reader.addEventListener('error', function(e){handleEvent(e, reader, fileTag)});
// reader.addEventListener('abort', function(e){handleEvent(e, reader, fileTag)});
}
// 이미지 파일에 핸들러 추가
function handleSelected(e, fileInput, reader, fileTag) {
const selectedFile = fileInput.files[0];
if (selectedFile) {
addListeners(reader, fileTag);
reader.readAsDataURL(selectedFile);
}
}
// 이미지 제거
function removeImage(fileInput, fileTag) {
document.querySelector('.'+fileTag+'-img-section').style.display = "none";
document.querySelector('.'+fileTag+'-img-preview').setAttribute('src', '#');
fileInput.value = '';
fileInput.required = true;
}
// 파일 바인딩 (실제로 수정해야 하는 부분)
const book_img_tag = "book";
const book_img_reader = new FileReader();
const book_img_file = document.querySelector('#'+book_img_tag+'_img');
book_img_file.addEventListener('change', function(e){handleSelected(e, this, book_img_reader, book_img_tag)});
if(document.querySelector('.'+book_img_tag+'-img-preview').getAttribute('src') != "#") {
document.querySelector('.'+book_img_tag+'-img-section').style.display = "block";
book_img_file.required = false;
}
document.querySelector('.'+book_img_tag+'-img-remove').addEventListener("click", () => {
removeImage(book_img_file, book_img_tag);
});
})();
/** END :: 이미지 관련 **/
</script>
참고자료
🔥developer.mozilla.org
javascript 코드를 참고하였으며, 필요한 방식으로 변형했습니다.
🔥pixabay.com
샘플 이미지를 사용했습니다.
🔥placeimg.com
샘플 이미지를 사용했습니다.
'Programming > JavaScript' 카테고리의 다른 글
JQuery :: paste or cut event to textarea in mobile :: 모바일 환경의 textarea 에서 잘라내기, 붙여넣기 이벤트 감지 (0) | 2022.12.16 |
---|---|
a tag disable :: a 태그 동적 비활성화 :: a 태그 링크 제거 (0) | 2022.09.03 |
정규식 후방탐색 사파리 대체 (0) | 2022.08.27 |
JavaScript 에서 정규식 활용하는 방법들 (0) | 2022.08.11 |
예제로 정리한 정규식 패턴 (0) | 2022.08.09 |