반응형
11-22 12:55
- Today
- Total
Link
개발하는 고라니
[Javascript] Image Slider 본문
반응형
프로젝트를 진행하던 중 글 상세조회 페이지에서 이미지를 보여주는데, 이미지가 여러개일 경우 한번에 다 나열해서 보여주기보다, 화살표나 버튼을 클릭해서 다음 이미지, 이전 이미지를 보는 것에 알게모르게 익숙해져있을 것이다. 그래서 트렌드에 맞게 이미지 슬라이더를 HTML, CSS, JS만으로 구현해보도록 하자.
먼저 결과를 보면 위와같은 UI가 될 것이다.
설계
구현을 하기에 앞서 어떻게 구현할지 설계를 해보았다.
가장 바깥에서 버튼들과 이미지가 보여질 곳(B)을 감싸는 녀석을 A라고 하고, 각각의 이미지(D)를 감싸는 프레임을 C라고 생각하면 된다.
# A
- display: flex
- justify-content: center
- align-items: center
- position: relative
# B
- display: flex
- position: relative
- width: 200px
- height: 200px
- overflow: hidden
# C
- position: absolute
- top: 0
- left: 0 (0이지만, 가변적으로 바뀜)
- display: flex
- transition: 0.5s
# D
- width: 200px
- height: 200px
그러면 다음과 같은 구조가 그려지게 된다.
HTML
<!-- Image Slider -->
<div class="slider-box"> <!-- A -->
<span class="btn-prev">prev</span> <!-- Btn prev -->
<div class="slider"> <!-- B -->
<div class="files"> <!-- C -->
<div th:each="file : *{attachments}" class="file"> <!-- D -->
<img class="thumbnail" th:src="@{/upload/{path}/{name}(path=${file.path}, name=${file.id + '_' + file.name})}">
</div>
</div>
</div>
<span class="btn-next">next</span> <!-- Btn next -->
<ul class="pagination">
</ul>
</div>
<!-- Image Slider -->
프로젝트에서 Thymeleaf를 사용하기 때문에 th: 속성을 사용하였는데 크게 개의치 않아도 된다.
CSS
/* slider-box */
.board .slider-box{
display: flex;
gap: 10px;
align-items: center;
justify-content: center;
height: 200px;
position: relative;
}
/* next / prev */
.slider-box span{
text-indent: -999px;
overflow: hidden;
display: block;
width: 24px;
height: 24px;
opacity: 0.5;
}
.slider-box .btn-prev{
background: #fff url("/image/board/prev.png") no-repeat center;
background-size: contain;
}
.slider-box .btn-next{
background: #fff url("/image/board/next.png") no-repeat center;
background-size: contain;
}
/* slider */
.slider{
position: relative;
/* pc -> 300px */
width: 200px;
height: 200px;
overflow: hidden;
}
.slider .files{
position: absolute;
top: 0;
left: 0;
display: flex;
transition: 0.5s;
}
.files .file{
/* pc -> 300px */
width: 200px;
height: 200px;
}
.file .thumbnail{
width: 100%;
height: 100%;
}
.slider-box .pagination{
background: transparent;
position: absolute;
bottom: 0;
z-index: 500;
display: flex;
gap: 5px;
height: 15px;
}
.pagination .item{
border-radius: 50%;
width: 8px;
height: 8px;
background: #707070;
}
.pagination .active{
background: #ff9c34 !important;
}
/* pagination */
JS
/* slider-Box */
const sliderBox = document.querySelector('.slider-box');
const slider = sliderBox.querySelector('.slider');
/* current slide Index */
let slideIndex = 0;
/* Items */
const file = sliderBox.querySelectorAll('.file');
const files = sliderBox.querySelector('.files');
/* number of slides */
const total = file.length;
/* frame width */
const sliderWidth = slider.clientWidth;
/* pagination */
const pagination = sliderBox.querySelector('.pagination');
/* set Pagination */
(() => {
let html = '';
for(let i=0; i<total; i++){
let active = '';
if(i === 0)
active = 'active';
html += `<li class="item ${active}"></li>`;
}
pagination.insertAdjacentHTML('beforeend', html);
})();
/* Next / Prev */
const btnNext = sliderBox.querySelector('.btn-next');
const btnPrev = sliderBox.querySelector('.btn-prev');
btnNext.addEventListener('click', (e) => {
plusSlides(1);
paging();
});
btnPrev.addEventListener('click', () => {
plusSlides(-1);
paging();
});
function plusSlides(n) {
showSlides(slideIndex += n);
}
function currentSlides(n){
showSlides(slideIndex = n);
}
function showSlides(n) {
slideIndex = n;
if(slideIndex == -1) {
slideIndex = total - 1;
}
else if(slideIndex === total){
slideIndex = 0;
}
files.style.left = -(sliderWidth * slideIndex) + 'px';
}
/* Paggination */
function paging(){
const items = pagination.querySelectorAll('li');
items.forEach((item, idx) => {
if(item.classList.contains('active'))
item.classList.remove('active');
});
items[slideIndex].classList.add('active');
}
반응형
'Languages > JS' 카테고리의 다른 글
[Javascript] Scroll 페이징 (0) | 2021.06.19 |
---|---|
[Javascript] Function (0) | 2021.06.17 |
[Javascript] Collections (0) | 2021.06.17 |
[Javascript] Image 미리보기 (0) | 2021.05.27 |
[Javascript] Ajax 모듈 (0) | 2021.05.06 |
Comments