슬라이드 이펙트 사용해보기 ( 6 ) 버튼,닷 슬라이드
슬라이드 이펙트를 버튼이나 닷을 누르면 이동하는 사이트를 만들어 보겠습니다.
VSCode
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>슬라이드 이펙트4</title>
<link rel="stylesheet" href="css/reset.css">
<link rel="stylesheet" href="css/slider.css">
<style>
/* slider__wrap */
.slider__wrap {
width: 100%;
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
}
.slider__img { /* 이미지가 보이는 영역 */
position: relative;
width: 800px;
height: 450px;
overflow: hidden;
}
.slider__inner { /* 이미지 움직이는 영역 */
display: flex;
flex-wrap: wrap;
width: 4800px;
height: 450px;
}
.slider { /* 개별적인 이미지 */
position: relative;
width: 800px;
height: 450px;
}
.slider__btn a {
position: absolute;
top: 50%;
transform: translateY(-50%);
width: 50px;
height: 50px;
text-align: center;
line-height: 50px;
border-radius: 50%;
background-color: blueviolet;
transition: all 0.3s;
}
.slider__btn a:hover {
background-color: red;
}
.slider__btn a.prev {
left: 0;
}
.slider__btn a.next {
right: 0;
}
.slider__dot {
position: absolute;
left: 50%;
bottom: 30px;
transform: translateX(-50%);
}
.slider__dot .dot {
width: 20px;
height: 20px;
background-color: rgba(255,255,255,0.3);
display: inline-block;
border-radius: 50%;
text-indent: -9999px;
transform: all 0.3s;
margin: 3px;
}
.slider__dot .dot.active {
background-color: #fff;
}
</style>
</head>
<body class="img09 bg04 font05">
<header id="header">
<h1>Javascript Slider Effect03</h1>
<p>슬라이드 이펙트 : 이미지 슬라이스(버튼, 닷 만들기)</p>
<ul>
<li><a href="sliderEffect01.html">1</a></li>
<li><a href="sliderEffect02.html">2</a></li>
<li><a href="sliderEffect03.html">3</a></li>
<li><a href="sliderEffect04.html">4</a></li>
<li><a href="sliderEffect05.html">5</a></li>
<li class="active"><a href="sliderEffect06.html">6</a></li>
<li><a href="sliderEffect07.html">7</a></li>
</ul>
</header>
<!-- //header-->
<main id="main">
<div class="slider__wrap">
<div class="slider__img">
<div class="slider__inner">
<div class="slider s1"><img src="./img/SliderEffect06-min.jpg" alt="이미지1"></div>
<div class="slider s2"><img src="./img/SliderEffect07-min.jpg" alt="이미지2"></div>
<div class="slider s3"><img src="./img/SliderEffect08-min.jpg" alt="이미지3"></div>
<div class="slider s4"><img src="./img/SliderEffect03-min.jpg" alt="이미지4"></div>
<div class="slider s5"><img src="./img/SliderEffect04-min.jpg" alt="이미지5"></div>
</div>
</div>
<div class="slider__btn">
<a href="#" class="prev" title="이전이미지">prev</a>
<a href="#" class="next" title="다음이미지">next</a>
</div>
<div class="slider__dot">
<!-- <a href="#" class="active dot">이미지1</a>
<a href="#" class="dot">이미지2</a>
<a href="#" class="dot">이미지3</a>
<a href="#" class="dot">이미지4</a>
<a href="#" class="dot">이미지5</a> -->
</div>
</div>
</main>
<!-- //main-->
<script>
//선택자
const sliderWrap = document.querySelector(".slider__wrap");
const sliderImg = sliderWrap.querySelector(".slider__img"); //보여지는 영역
const sliderInner = sliderWrap.querySelector(".slider__inner"); //움직이는 영역
const slider = sliderWrap.querySelectorAll(".slider"); //개별 이미지
const sliderDot = sliderWrap.querySelector(".slider__dot"); //닷 메뉴
const sliderBtn = sliderWrap.querySelectorAll(".slider__btn a"); //이전,다음 버튼
let currentIndex = 0; //현재 보이는 이미지
let sliderCount = slider.length; //이미지 갯수
let sliderInterval = 3000; //이미지 변경 간격 시간
let sliderWidth = slider[0].offsetWidth; //이미지 가로값
let dotIndex = "";
function init(){
//이미지 갯수만큼 닷 메뉴 생성
slider.forEach(() =>dotIndex += "<a href='#' class='dot'>이미지</a>");
sliderDot.innerHTML = dotIndex;
//첫번째 닷 메뉴한테 활성화 표시
sliderDot.firstChild.classList.add("active");
}
init();
//이미지 이동시키기
function gotoSlider(num){
sliderInner.style.transition = "all 400ms";
sliderInner.style.transform = "translateX("+ -sliderWidth * num+"px)"
currentIndex = num;
let dotActive = document.querySelectorAll(".slider__dot .dot");
dotActive.forEach((active) => active.classList.remove("active"));
dotActive[num].classList.add("active");
}
//버튼을 클릭했을 때
sliderBtn.forEach((btn, index) => {
btn.addEventListener("click", () => {
let prevIndex = (currentIndex+ (sliderCount-1)) % sliderCount ;
let nextIndex = (currentIndex+1) % sliderCount;
if(btn.classList.contains("prev")){
gotoSlider(prevIndex);
} else {
gotoSlider(nextIndex);
}
});
});
//닷 클릭했을때 사진으로 이동
let dotClick = sliderWrap.querySelectorAll(".slider__dot .dot");
dotClick.forEach((el,i)=>{
el.addEventListener("click", ()=>{
//이미지 이동시키기 함수 우려먹기
gotoSlider(i);
})
})
</script>
</body>
</html>
화면 밑에 누를 수 있고 현재 화면을 표시하는 닷(dot) 을 만들었습니다.
slider__dot 이라는 클래스를 만들었고 이미지 갯수만큼 닷 갯수를 만들기 위해 스크립트 안에서 dot을 만듭니다.
function init(){
//이미지 갯수만큼 닷 메뉴 생성
slider.forEach(() =>dotIndex += "<a href='#' class='dot'>이미지</a>");
sliderDot.innerHTML = dotIndex;
//첫번째 닷 메뉴한테 활성화 표시
sliderDot.firstChild.classList.add("active");
}
init();
slider 배열에 저장된 이미지 갯수만큼 forEach() 메소드를 사용하여 닷 메뉴를 생성합니다. 이때 dotIndex 변수는 생성된 각 닷 메뉴의 HTML 코드를 저장하는 문자열입니다.
그 다음, sliderDot 요소에 innerHTML 프로퍼티를 사용하여 dotIndex 변수에 저장된 HTML 코드를 삽입합니다. 이렇게 하면 닷 메뉴가 슬라이드 쇼와 함께 화면에 표시됩니다.
마지막으로, sliderDot 요소의 첫번째 자식 요소(즉, 첫번째 닷 메뉴)에 classList 프로퍼티의 add() 메소드를 사용하여 "active" 클래스를 추가합니다. 이렇게 하면 첫번째 닷 메뉴가 활성화된 상태로 표시되어 슬라이드 쇼가 시작됩니다.
//이미지 이동시키기
function gotoSlider(num){
sliderInner.style.transition = "all 400ms";
sliderInner.style.transform = "translateX("+ -sliderWidth * num+"px)"
currentIndex = num;
let dotActive = document.querySelectorAll(".slider__dot .dot");
dotActive.forEach((active) => active.classList.remove("active"));
dotActive[num].classList.add("active");
}
gotoSlider() 함수는 인자로 전달받은 num 값에 따라 sliderInner 요소의 transform 속성을 변경하여 이미지를 이동시킵니다. 이때 sliderWidth 변수는 각 이미지의 너비를 저장하고 있으며, num 값에 따라서 translateX 속성값이 변경됩니다. 즉, num 값이 0이면 0px, 1이면 -1000px, 2이면 -2000px, ...와 같이 이미지를 왼쪽으로 이동시킵니다. 이동 애니메이션 효과를 위해 transition 속성도 추가되어 있습니다.
다음으로, currentIndex 변수에 num 값을 저장하여 현재 이미지의 인덱스를 유지합니다.
마지막으로, querySelectorAll() 메소드를 사용하여 dotActive 변수에 모든 닷 메뉴 요소를 저장하고, forEach() 메소드를 사용하여 각 요소에서 "active" 클래스를 제거합니다. 그 다음, dotActive[num] 요소(즉, 인덱스가 num인 닷 메뉴)에 classList 프로퍼티의 add() 메소드를 사용하여 "active" 클래스를 추가합니다. 이렇게 하면 현재 보여지는 이미지와 해당하는 닷 메뉴가 활성화된 상태로 표시됩니다.
//버튼을 클릭했을 때
sliderBtn.forEach((btn, index) => {
btn.addEventListener("click", () => {
let prevIndex = (currentIndex+ (sliderCount-1)) % sliderCount ;
let nextIndex = (currentIndex+1) % sliderCount;
if(btn.classList.contains("prev")){
gotoSlider(prevIndex);
} else {
gotoSlider(nextIndex);
}
});
});
sliderBtn 배열에 저장된 이전 버튼과 다음 버튼 요소들을 forEach() 메소드를 사용하여 순차적으로 탐색합니다. 각 버튼 요소에 대해 addEventListener() 메소드를 사용하여 클릭 이벤트를 등록합니다.
클릭 이벤트가 발생하면, currentIndex 변수를 기준으로 이전 이미지의 인덱스(prevIndex)와 다음 이미지의 인덱스(nextIndex)를 계산합니다. 이때 sliderCount 변수는 슬라이드 쇼에 사용되는 이미지의 총 갯수를 저장하고 있습니다. 계산식에서 % 연산자는 나머지 연산을 수행하므로, prevIndex가 0보다 작은 경우에는 sliderCount-1 값이 더해져 마지막 이미지의 인덱스로 이동하게 됩니다.
마지막으로, 이전 버튼을 클릭한 경우 gotoSlider() 함수에 prevIndex 값을 전달하여 해당하는 이미지로 이동시키고, 다음 버튼을 클릭한 경우 gotoSlider() 함수에 nextIndex 값을 전달하여 해당하는 이미지로 이동시킵니다.
//닷 클릭했을때 사진으로 이동
let dotClick = sliderWrap.querySelectorAll(".slider__dot .dot");
dotClick.forEach((el,i)=>{
el.addEventListener("click", ()=>{
//이미지 이동시키기 함수 우려먹기
gotoSlider(i);
})
})
sliderWrap 요소의 자식 요소 중 클래스가 "slider__dot"인 요소의 자식 요소 중 클래스가 "dot"인 모든 요소를 선택하여 dotClick 변수에 저장합니다. 이후 forEach() 메소드를 사용하여 각 닷 메뉴 요소에 대해 클릭 이벤트를 등록합니다.
클릭 이벤트가 발생하면, 해당 닷 메뉴의 인덱스값(i)을 gotoSlider() 함수에 전달하여 해당하는 이미지로 슬라이드 쇼를 이동시킵니다.
이렇게 구현된 코드는 사용자가 닷 메뉴를 클릭하면 해당하는 이미지로 바로 이동할 수 있도록 하는 기능을 추가합니다.