웹에서 이미지를 업로드할 때, 사용자가 실시간으로 이미지를 확인할 수 있다면 어떨까요?
웹 개발을 하다 보면 사용자의 파일 업로드를 처리해야 할 상황이 자주 발생합니다. 특히 이미지 파일의 경우, 업로드 후 미리보기를 제공하면 사용자 만족도를 크게 높일 수 있습니다. 이번 포스트에서는 jQuery를 활용하여 이미지 파일을 업로드하고 미리 보는 기능을 어떻게 구현하는지 알아보겠습니다.
HTML 구조
1
2
3
4
5
6
7
8
9
10
| <div class="image_file">
<label>
<span class="upload"><img src="images/image_file_upload.png" alt="이미지 업로드"></span>
<input type="file" class="file_input" accept="image/*">
</label>
<div class="preview">
<span class="img_box"><img class="preview_img" src="#" alt="Selected Image"></span>
<button type="button" class="delect"><img src="images/image_file_delect.png" alt="삭제"></button>
</div>
</div>
|
업로드 라벨 및 버튼
label 안에 있는 span 요소가 업로드 버튼처럼 작동하며, 클릭 시 파일 선택창이 열립니다.
버튼에는 직관적인 이미지가 적용되어 사용자 입장에서 사용하기 편리합니다.
미리보기 영역
이미지를 선택하면 .preview 영역이 나타나고, 선택한 이미지와 삭제 버튼이 함께 노출됩니다.
사용자는 선택한 이미지를 바로 확인하고 원하면 다시 변경할 수 있습니다.
여러 개의 이미지 업로드 필드 구성하기
.image_file 클래스를 여러 번 사용하면, 각 필드마다 독립적으로 이미지 업로드와 미리보기 기능을 구현할 수 있습니다. 이를 활용하면 여러 장의 이미지를 업로드해야 하는 폼에서도 쉽게 적용할 수 있습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| <!-- 첫 번째 이미지 업로드 필드 -->
<div class="image_file">
<label>
<span class="upload"><img src="images/image_file_upload.png" alt="이미지 업로드"></span>
<input type="file" class="file_input" accept="image/*">
</label>
<div class="preview">
<span class="img_box"><img class="preview_img" src="#" alt="선택한 이미지"></span>
<button type="button" class="delect"><img src="images/image_file_delect.png" alt="삭제"></button>
</div>
</div>
<!-- 두 번째 이미지 업로드 필드 -->
<div class="image_file">
<label>
<span class="upload"><img src="images/image_file_upload.png" alt="이미지 업로드"></span>
<input type="file" class="file_input" accept="image/*">
</label>
<div class="preview">
<span class="img_box"><img class="preview_img" src="#" alt="선택한 이미지"></span>
<button type="button" class="delect"><img src="images/image_file_delect.png" alt="삭제"></button>
</div>
</div>
|
이처럼 구조만 반복해서 작성하면, 자바스크립트가 각 .image_file 요소를 기준으로 동작하므로 서로 간섭 없이 각각 이미지 업로드와 삭제 기능을 사용할 수 있습니다.
CSS 스타일
1
2
3
4
5
6
7
8
9
10
| .image_file { position: relative; width: 200px; height: 200px; margin: 150px auto 0; }
.image_file label { display: block; height: 100%; cursor: pointer; }
.image_file .upload { display: flex; height: 100%; border: 1px dashed #E5E5E5; border-radius: 6px; justify-content: center; align-items: center; background: #FFFFFF; }
.image_file .upload img { width: 40px; height: 40px; }
.image_file .file_input { position: absolute; width: 1px; height: 1px; margin: -1px; font-size: initial; overflow: hidden; clip: rect(0, 0, 0, 0); }
.image_file .preview { display: none; position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
.image_file .preview .img_box { display: block; height: 100%; border: 1px solid #E5E5E5; border-radius: 6px; background: #FFFFFF; cursor: pointer; }
.image_file .preview .preview_img { width: 100%; height: 100%; object-fit: cover; }
.image_file .preview .delect { position: absolute; top: 15px; right: 15px; width: 25px; height: 25px; padding: 0; border: none; background: none; cursor: pointer; }
.image_file .preview .delect img { width: 100%; }
|
전체 컨테이너
.image_file 클래스는 업로드 UI 전체를 감싸며 크기, 위치, 정렬 등 레이아웃을 구성합니다.
업로드 버튼 스타일
.upload 클래스는 업로드 버튼을 보기 좋게 꾸며주며, 클릭 유도에 효과적인 스타일이 적용됩니다.
중앙 정렬과 테두리 스타일로 사용자가 클릭하고 싶은 요소로 만듭니다.
파일 입력 숨김 처리
input[type=“file”]은 기본 스타일을 완전히 숨기고, 대신 시각적인 요소가 클릭을 담당합니다.
이로 인해 UI는 깔끔하게 유지되며, 기능은 그대로 유지됩니다.
미리보기 스타일
선택된 이미지를 전체 영역에 꽉 채워 보여주며, 삭제 버튼은 항상 일정 위치에 고정됩니다.
jQuery 코드
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
| $(document).ready(function(){
imageFileUpload()
})
// 이미지 파일 업로드 버튼
function imageFileUpload() {
$('.image_file .delect').on('click', handleDeleteClick);
$('.image_file .file_input').on('change', handleFileInputChange);
// 미리보기 이미지 클릭 시 파일 입력 요소 클릭 이벤트 트리거
$('.image_file .preview_img').on('click', function() {
$(this).closest('.image_file').find('.file_input').click(); // 파일 입력 요소 클릭
});
// 파일 입력 변경 시 미리보기 이미지 업데이트
function handleFileInputChange() {
const file = this.files[0]; // 선택된 파일
const previewContainer = $(this).closest('.image_file').find('.preview'); // 미리보기 컨테이너
const previewImage = previewContainer.find('.preview_img'); // 미리보기 이미지 요소
if (file) {
const reader = new FileReader(); // 파일 리더 생성
reader.onload = (e) => {
previewImage.attr('src', e.target.result); // 미리보기 이미지 설정
previewContainer.show(); // 미리보기 컨테이너 표시
previewContainer.closest('.image_file').find('.upload').hide(); // 업로드 버튼 숨김
};
reader.readAsDataURL(file); // 파일을 데이터 URL로 읽기
} else {
resetPreview(previewContainer); // 파일이 선택되지 않았거나 취소된 경우 미리보기 초기화
}
let file_cnt=0;
$('.file_select_pop .file_input').map(function(){
if($(this).val()) file_cnt++;
});
$('.file_select_pop .file_cnt').html(file_cnt);
}
// 삭제 버튼 클릭 시 미리보기 및 파일 입력 초기화
function handleDeleteClick() {
const previewContainer = $(this).closest('.preview'); // 미리보기 컨테이너
resetPreview(previewContainer);
let file_cnt=0;
$('.file_select_pop .file_input').map(function(){
if($(this).val()) file_cnt++;
});
$('.file_select_pop .file_cnt').html(file_cnt);
}
// 미리보기 및 파일 입력 초기화
function resetPreview(previewContainer) {
const imageFileContainer = previewContainer.closest('.image_file'); // 이미지 파일 컨테이너
imageFileContainer.find('.file_input').val(''); // 파일 입력 요소 초기화
previewContainer.hide(); // 미리보기 컨테이너 숨김
imageFileContainer.find('.upload').show(); // 업로드 버튼 다시 표시
}
}
|
이벤트 리스너 설정
파일 선택과 삭제 버튼에 각각 이벤트를 연결해, 상황에 따라 기능이 정확하게 작동하도록 합니다.
각 기능이 명확하게 분리되어 있어 코드 구조도 깔끔합니다.
미리보기 이미지 클릭
미리보기 이미지를 클릭하면 다시 파일 선택창이 열려 이미지를 다시 선택할 수 있습니다.
직접 input을 클릭하는 대신 자연스러운 흐름으로 기능이 실행됩니다.
이미지 변경 시 처리
사용자가 파일을 선택하면 FileReader를 통해 이미지를 불러와 미리보기에 표시합니다.
선택 직후 업로드 버튼은 숨겨지고 미리보기 화면이 활성화됩니다.
삭제 시 처리
삭제 버튼 클릭 시 입력값과 미리보기가 모두 초기화되어, 사용자가 다시 이미지를 업로드할 수 있습니다.
초기화 함수
파일 입력값과 미리보기를 모두 초기 상태로 되돌리는 역할을 합니다.
업로드 영역도 다시 활성화되며, 사용자가 곧바로 새로운 이미지를 선택할 수 있습니다.
결론
이번 포스트에서는 jQuery를 활용한 이미지 업로드 및 미리보기 기능을 단계별로 구현해 보았습니다.
이미지를 선택하면 바로 미리보기가 표시되고, 삭제나 재선택도 간편하게 할 수 있어 누구나 쉽게 사용할 수 있습니다.
클릭 몇 번만으로 필요한 기능을 빠르게 사용할 수 있다는 점도 큰 장점입니다.
이 포스팅이 유익하셨다면 댓글로 의견 남겨주세요!
더 좋은 방향으로 함께 고민해 보면 좋겠습니다. 😊