Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 자바
- react
- 코드업
- 프론트엔드
- CSS
- 코딩테스트
- 그럼에도불구하고
- node
- java
- react-router-dom
- github
- JS
- git
- JavaScript
- HTML
- 반응형 페이지
- max-width
- node.js
- Servlet
- cleancode
- webpack
- media query
- 변수
- 그럼에도 불구하고
- TypeScript
- redux
- 자바문제풀이
- @media
- frontend
- coding
Archives
- Today
- Total
그럼에도 불구하고
FileReader 객체 사용하여 image 올리기 본문
FileReader 객체 사용하여 image 올려보자
ref:
조건
1. 파일을 올릴 수 있는 버튼을 누르면 파일을 올린다.
2. 올릴 파일은 image로 제한한다.
3. 파일은 한 개만 올릴 수도 있고 다수도 가능하다. (여기서는 4개)
4. 각 파일마다 파일명, 사이즈, 파일타입을 알려준다.
CSS
더보기
* {
margin: 0;
padding: 0;
}
body {
margin: 20px;
}
#image {
display: none;
}
.form-container {
display: flex;
margin: 20px 0;
gap: 20px;
}
.img-upload-btn {
display: inline-block;
width: 200px;
height: 50px;
background-color: skyblue;
border-radius: 10px;
cursor: pointer;
text-align: center;
line-height: 50px;
box-shadow: inset 0 0 10px rgb(106, 170, 196);
}
#fileName-preview {
width: 400px;
height: 50px;
border-radius: 10px;
background-color: #feefef;
text-indent: 1rem;
border: 1px solid #fddfdf;
}
.log {
display: flex;
gap: 70px;
}
.img-preview {
display: flex;
justify-content: space-evenly;
width: 2200px;
height: 540px;
box-sizing: content-box;
border: 10px solid black;
border-radius: 50px;
}
.img-preview img {
margin: 20px;
width: 500px;
height: 500px;
gap: 50px;
border: 3px solid slategray;
border-radius: 30px;
}
l;kl;kl
HTML
더보기
<h1>이미지 미리보기</h1>
<div class="form-container">
<input type="text" id="fileName-preview" disabled placeholder="파일을 선택하세요.">
<label for="image" class="img-upload-btn"> 이미지업로드 </label>
<input type="file" id="image" accept="image/*" multiple>
<!-- 여러개 파일 업로드 -->
</div>
<div class="log"></div>
<div class="img-preview">
<!-- <img src="" alt=""> -->
</div>
JavaScript
<script>
const getFileBtn = document.querySelector('#image');
getFileBtn.addEventListener('change', (event) => {
let route = event.srcElement.files;
document.querySelector('#fileName-preview').value = (`
${route[0].name}외 ${route.length - 1}개 선택
`).trim();
for (let i = 0; i < route.length; i++) {
log.innerHTML += `
<div>상세정보</div>
파일명 : ${route[i].name} <br>
사이즈 : ${sizeCalculater(route[i].size)} <br>
파일타입 : ${route[i].type}
`
}
const imgPreview = document.querySelector('.img-preview');
imgPreview.innerHTML = "";
// route를 배열화
[...route].forEach((data) => {
if (data.type.includes('image')) {
// 파일 제한을 둬서 이미지만 골라서 출력
const fileReader = new FileReader();
fileReader.readAsDataURL(data);
fileReader.addEventListener('load', (event) => {
const img = document.createElement('img');
img.setAttribute('src', event.target.result);
imgPreview.appendChild(img);
})
}
})
})
// 메모리에 바이널리 코드로 저장 했다가 바꿔주는 작업
function sizeCalculater(size) {
const UNIT = 1024;
if (size <= UNIT) {
return size + 'byte'
} else if (size > UNIT && size <= UNIT ** 2) {
return (size / UNIT).toFixed(1) + "KB"
} else if (size > UNIT ** 2 && size <= UNIT ** 3) {
return (size / UNIT**2).toFixed(1) + "MB"
} else if (size1 > UNIT ** 3 && size <= UNIT ** 4) {
return (size / UNIT**3).toFixed(1) + "GB"
}
}
</script>
자주 사용하는 경로는 여러번 쓰지 않고 변수로 초기화시켜 사용한다.
let route = event.srcElement.files;
내가 upload한 file명과 상세정보를 보여준다.
document.querySelector('#fileName-preview').value = (`
${route[0].name}외 ${route.length - 1}개 선택
`).trim();
for (let i = 0; i < route.length; i++) {
log.innerHTML += `
<div>상세정보</div>
파일명 : ${route[i].name} <br>
사이즈 : ${sizeCalculater(route[i].size)} <br>
파일타입 : ${route[i].type}
`
}
route를 배열화하여 이미지를 upload 한다.
// route를 배열화
[...route].forEach((data) => {
if (data.type.includes('image')) {
// 파일 제한을 둬서 이미지만 골라서 출력
const fileReader = new FileReader();
fileReader.readAsDataURL(data);
fileReader.addEventListener('load', (event) => {
const img = document.createElement('img');
img.setAttribute('src', event.target.result);
imgPreview.appendChild(img);
})
}
})
상세정보 업로드시 용량을 바이트 단위로 환산한다.
// 메모리에 바이널리 코드로 저장 했다가 바꿔주는 작업
function sizeCalculater(size) {
const UNIT = 1024;
if (size <= UNIT) {
return size + 'byte'
} else if (size > UNIT && size <= UNIT ** 2) {
return (size / UNIT).toFixed(1) + "KB"
} else if (size > UNIT ** 2 && size <= UNIT ** 3) {
return (size / UNIT**2).toFixed(1) + "MB"
} else if (size1 > UNIT ** 3 && size <= UNIT ** 4) {
return (size / UNIT**3).toFixed(1) + "GB"
}
}
결과
See the Pen Untitled by zenghyun (@zenghyun) on CodePen.
개선
JavaScript 코드가 비효율적으로 보였다.
getFileBtn을 눌렀을 때 'change' event가 발생하는 구문안에 다수의 기능이 들어 있었다.
1. 함수로 나눠서 하나의 함수는 하나의 기능만 하게 바꾼다.
2. 상세정보를 upload할 때 for문을 사용하지 않고 route를 배열화 해서 upload 한다.
3. 이미지 upload시 [...route]와 같이 쓰지 않고 2번에서 route를 배열화한 객체를 사용한다.
<script>
"use strict";
const getFileBtn = document.querySelector('#image');
getFileBtn.addEventListener('change', (event) => {
let route = event.srcElement.files;
const routeAry = Array.from(route);
let fileName = document.querySelector('#fileName-preview');
fileName.value = (`
${route[0].name}외 ${route.length - 1}개 선택
`).trim();
showLog(routeAry);
showImg(routeAry);
})
// upload한 정보
function showLog(routeAry) {
const log = document.querySelector('.log');
routeAry.forEach((value) => {
log.innerHTML += `
<div>상세정보</div>
파일명 : ${value.name} <br>
사이즈 : ${sizeCalculater(value.size)} <br>
파일타입 : ${value.type}
`;
})
}
// upload한 image
function showImg(routeAry) {
const imgPreview = document.querySelector('.img-preview');
imgPreview.innerHTML = "";
routeAry.forEach((data) => {
if (data.type.includes('image')) {
// 파일 제한을 둬서 이미지만 골라서 출력
const fileReader = new FileReader();
fileReader.readAsDataURL(data);
fileReader.addEventListener('load', (event) => {
const img = document.createElement('img');
img.setAttribute('src', event.target.result);
imgPreview.appendChild(img);
})
}
})
}
// 메모리에 바이널리 코드로 저장 했다가 바꿔주는 작업
function sizeCalculater(size) {
const UNIT = 1024;
if (size <= UNIT) {
return size + 'byte'
} else if (size > UNIT && size <= UNIT ** 2) {
return (size / UNIT).toFixed(1) + "KB"
} else if (size > UNIT ** 2 && size <= UNIT ** 3) {
return (size / UNIT**2).toFixed(1) + "MB"
} else if (size1 > UNIT ** 3 && size <= UNIT ** 4) {
return (size / UNIT**3).toFixed(1) + "GB"
}
}
</script>
결과는 동일하게 나오지만 이게 더 명료하고 가독성도 좋은 것 같다.
'JavaScript > Function implementation' 카테고리의 다른 글
아날로그 시계 만들기 (0) | 2023.01.07 |
---|---|
mousemove 이벤트로 색 변환하기 (0) | 2023.01.06 |
배열 무작위 섞기 (셔플) (0) | 2023.01.05 |
array.sort() 오름차순, 내림차순 정렬하기 (0) | 2023.01.04 |
encodeURIComponent로 네이버 검색하기 (0) | 2023.01.03 |
Comments