[UI] 슬라이드 배너(Slide Banner)
설명
vanillaJS로 만들어본 기본 슬라이드 배너
조건
- 라이브러리 없이 자바스크립트만 활용
- 다음, 이전 버튼으로 슬라이드 조작 가능
- 인디게이터는 슬라이드 갯수에 맞게 자동으로 생성
- 자동재생, 일시정지 버튼으로 웹 접근성 준수
구현
See the Pen [VanillaJs] 슬라이드 배너 by recordboy (@recordboy) on CodePen.
HTML
<div id="slide">
<ul class="cnt">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
<div class="btn">
<button type="button" class="prev">prev</button>
<button type="button" class="next">next</button>
</div>
<div class="auto">
<button type="button" class="stop">stop</button>
<button type="button" class="play">play</button>
</div>
</div>
CSS
#slide {
position: relative;
overflow: hidden;
width: 300px;
height: 300px;
}
#slide .cnt > li {
position: absolute;
top: 0;
left: 300px;
width: 300px;
height: 300px;
text-align: center;
font-size: 30px;
line-height: 300px;
color: #fff;
}
#slide .cnt > li:nth-child(1) {
background-color: red;
}
#slide .cnt > li:nth-child(2) {
background-color: orange;
}
#slide .cnt > li:nth-child(3) {
background-color: green;
}
#slide .cnt > li:nth-child(4) {
background-color: blue;
}
#slide .btn > button {
position: absolute;
top: 50%;
transform: translateY(-50%);
border: 0;
padding: 5px;
background-color: #fff;
}
#slide .btn .prev {
left: 5px;
}
#slide .btn .next {
right: 5px;
}
#slide .auto > button {
display: none;
position: absolute;
bottom: 5px;
right: 5px;
border: 0;
padding: 5px;
background-color: #fff;
}
#slide .indi {
position: absolute;
bottom: 10px;
left: 50%;
transform: translateX(-50%);
}
#slide .indi:after {
content: "";
display: block;
clear: both;
}
#slide .indi > li {
float: left;
margin-left: 5px;
border-radius: 50%;
width: 12px;
height: 12px;
cursor: pointer;
opacity: 0.5;
background-color: #fff;
}
#slide .indi > li.on {
opacity: 1;
}
#slide .indi > li:first-child {
margin-left: 0;
}
JavaScript
window.addEventListener("load", function () {
var MOVEING_PX = 4,
AUTO_TIME = 2000,
slide = document.getElementById("slide"),
indi = document.createElement("ul"),
slideCnt = slide.getElementsByClassName("cnt"),
slideCntItem = slideCnt[0].getElementsByTagName("li"),
prevBtn = slide.getElementsByClassName("prev"),
nextBtn = slide.getElementsByClassName("next"),
playBtn = slide.getElementsByClassName("play"),
stopBtn = slide.getElementsByClassName("stop"),
playSet = null,
before = 0,
after = 0,
moveIng = false;
// init
slideCntItem[0].style.left = 0;
playBtn[0].style.display = "block";
var indi = document.createElement("ul");
for (var i = 0; i < slideCntItem.length; i++) {
indi.innerHTML += "<li></li>";
}
indi.classList.add("indi");
indi.children[0].classList.add("on");
slide.append(indi);
for (var j = 0; j < indi.children.length; j++) {
indiClick(j);
}
// initEvnet
nextBtn[0].addEventListener("click", function (e) {
if (!moveIng) {
after++;
if (after >= slideCntItem.length) {
after = 0;
}
move(after, before, "next");
before = after;
}
});
prevBtn[0].addEventListener("click", function (e) {
if (!moveIng) {
after--;
if (after < 0) {
after = slideCntItem.length - 1;
}
move(after, before);
before = after;
}
});
playBtn[0].addEventListener("click", function () {
playBtn[0].style.display = "none";
stopBtn[0].style.display = "block";
playSet = setInterval(function () {
if (!moveIng) {
after++;
if (after >= slideCntItem.length) {
after = 0;
}
move(after, before, "next");
before = after;
}
}, AUTO_TIME);
});
stopBtn[0].addEventListener("click", function () {
playBtn[0].style.display = "block";
stopBtn[0].style.display = "none";
clearInterval(playSet);
});
function indiClick(target) {
indi.children[target].addEventListener("click", function () {
if (!moveIng) {
after = target;
if (after > before) {
move(after, before, "next");
} else if (after < before) {
move(after, before);
}
before = after;
}
});
}
function move(after, before, type) {
var nextX = type === "next" ? slide.offsetWidth : slide.offsetWidth * -1,
prevX = 0,
set = null;
set = setInterval(function () {
moveIng = true;
if (type === "next") {
nextX -= MOVEING_PX;
slideCntItem[after].style.left = nextX + "px";
if (nextX <= 0) {
clearInterval(set);
nextX = slide.offsetWidth;
moveIng = false;
}
prevX -= MOVEING_PX;
} else {
nextX += MOVEING_PX;
slideCntItem[after].style.left = nextX + "px";
if (nextX >= 0) {
clearInterval(set);
nextX = slide.offsetWidth * -1;
moveIng = false;
}
prevX += MOVEING_PX;
}
slideCntItem[before].style.left = prevX + "px";
});
indi.children[before].classList.remove("on");
indi.children[after].classList.add("on");
}
});