Skip to content

Instantly share code, notes, and snippets.

@minjeongss
Last active August 5, 2024 05:26
Show Gist options
  • Save minjeongss/53fcf5a270d320abc5e62dab41c7a279 to your computer and use it in GitHub Desktop.
Save minjeongss/53fcf5a270d320abc5e62dab41c7a279 to your computer and use it in GitHub Desktop.
DevCourse_SlideAssignment

무한 슬라이드 제작기

기능

무한 슬라이드

handlePrevMove

handleNExtMove

페이지네이션

handlePageIndex

handlePagination

updatePagination

이벤트

Prev, Next 버튼 클릭하기

Pagination 버튼 클릭하기

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Slide</title>
<link rel="stylesheet" href="./slide.css" />
<script src="./slide.js" defer></script>
</head>
<body>
<main>
<section class="slide">
<div class="slide-wrap">
<ul class="slider-ul">
<li class="slider">
<div>
<p>1</p>
<img
src="https://plus.unsplash.com/premium_photo-1722009043668-b3c470595df9?q=80&w=1287&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
alt=""
/>
</div>
</li>
<li class="slider">
<div>
<p>2</p>
<img
src="https://images.unsplash.com/photo-1631803887118-e626f7a7c78d?q=80&w=1287&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
alt=""
/>
</div>
</li>
<li class="slider">
<div>
<p>3</p>
<img
src="https://images.unsplash.com/photo-1722648404090-2179fba1b4b0?q=80&w=1470&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
alt=""
/>
</div>
</li>
<li class="slider">
<div>
<p>4</p>
<img
src="https://images.unsplash.com/photo-1632154041369-8d8d3ebe6c73?q=80&w=1287&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
alt=""
/>
</div>
</li>
</ul>
</div>
<button class="btn prev"><</button>
<button class="btn next">></button>
<div class="slider-dot">
<span class="dot1"></span>
<span class="dot2"></span>
<span class="dot3"></span>
<span class="dot4"></span>
</div>
</section>
</main>
</body>
</html>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
li {
list-style: none;
}
img {
width: 100%;
}
.slide {
position: relative;
width: 80%;
max-width: 600px;
top: 30px;
margin: auto;
/* border: 5px solid lightgray; */
}
.slide-wrap {
/* border: 5px solid tomato; */
overflow: hidden;
border-radius: 10px;
}
.btn,
.slider-dot {
z-index: 100;
position: absolute;
}
.btn {
top: 50%;
cursor: pointer;
width: 30px;
height: 30px;
border-radius: 10px;
border: 2px solid #6482ad;
background-color: white;
color: #7fa1c3;
font-weight: 800;
}
.btn:hover {
background-color: #6482ad;
color: white;
}
.prev {
left: -40px;
}
.next {
right: -40px;
}
.slider-dot {
display: relative;
bottom: -30px;
width: 130px;
height: 10px;
left: calc(43%);
}
.slider-dot > span {
position: absolute;
width: 10px;
height: 10px;
border-radius: 50%;
background-color: lightgrey;
}
.slider-dot > span.on {
background-color: #7fa1c3;
}
.slider-dot > span:hover {
cursor: pointer;
background-color: #6482ad;
}
.dot1 {
left: 0;
}
.dot2 {
left: 30px;
}
.dot3 {
left: 60px;
}
.dot4 {
left: 90px;
}
.slider-ul {
/* border: 2px solid slateblue; */
display: flex;
width: 400%;
transform: translateX(-25%);
transition: transform 0.5s ease;
}
/* .slider-ul.hidden {
visibility: hidden;
} */
.slider {
/* border: 5px solid red; */
width: calc(100% / 4);
}
.slider:nth-of-type(3) ~ .slider {
display: none;
}
.slider > div {
position: relative;
padding-top: 35%;
overflow: hidden;
}
.slider > div > * {
position: absolute;
top: 0;
left: 0;
}
.slider > div img {
width: 100%;
height: 100%;
object-fit: cover;
}
.slider > div p {
z-index: 1;
/* background-color: black; */
color: white;
padding: 2rem;
}
@media (max-width: 800px) {
.btn {
display: none;
}
}
const $btns = document.querySelectorAll(".btn");
const $prevBtn = document.querySelector(".prev");
const $nextBtn = document.querySelector(".next");
const $sliderDot = document.querySelector(".slider-dot");
const $dots = $sliderDot.querySelectorAll("span");
let isAnimating = false; // 애니메이션 진행중 여부
const handlePrevMove = (changeCount) => {
if (isAnimating) return;
isAnimating = true;
const $sliderUl = document.querySelector(".slider-ul");
const $slider = document.querySelectorAll(".slider");
for (let i = 0; i < changeCount; i++) {
const lastElement = $sliderUl.lastElementChild.cloneNode(true);
console.log(lastElement);
$sliderUl.removeChild($sliderUl.lastElementChild);
$sliderUl.insertBefore(lastElement, $sliderUl.firstElementChild);
}
$sliderUl.style.transition = "none";
$sliderUl.style.transform = "translateX(-50%)";
requestAnimationFrame(() => {
requestAnimationFrame(() => {
$sliderUl.style.transition = "transform 0.5s ease";
$sliderUl.style.transform = "translateX(-25%)";
$sliderUl.addEventListener(
"transitionend",
() => {
isAnimating = false;
updatePagination();
},
{ once: true }
);
});
});
};
const handleNextMove = (changeCount) => {
if (isAnimating) return;
isAnimating = true;
const $sliderUl = document.querySelector(".slider-ul");
const $slider = document.querySelectorAll(".slider");
for (let i = 0; i < changeCount; i++) {
const firstElement = $sliderUl.firstElementChild.cloneNode(true);
console.log(firstElement);
$sliderUl.removeChild($sliderUl.firstElementChild);
$sliderUl.appendChild(firstElement);
}
$sliderUl.style.transition = "none";
$sliderUl.style.transform = "translateX(0)";
requestAnimationFrame(() => {
requestAnimationFrame(() => {
$sliderUl.style.transition = "transform 0.5s ease";
$sliderUl.style.transform = "translateX(-25%)";
$sliderUl.addEventListener(
"transitionend",
() => {
isAnimating = false;
updatePagination();
},
{ once: true }
);
});
});
};
const handlePageIndex = (item) => {
const $slider = document.querySelectorAll(".slider");
const $sliderIndex = Number($slider[1].innerText);
const $paginationIndex = Number(item.classList[0][3]);
console.log("slider", $sliderIndex, " /pagination", $paginationIndex);
let diffIndex = $sliderIndex - $paginationIndex;
return diffIndex;
};
const handlePagination = (item) => {
let diffIndex = handlePageIndex(item);
console.log(diffIndex);
if (diffIndex < 0) {
diffIndex = Math.abs(diffIndex);
handleNextMove(diffIndex);
} else if (diffIndex > 0) {
handlePrevMove(diffIndex);
}
};
const updatePagination = () => {
const $slider = document.querySelectorAll(".slider");
const currentSliderIndex = Number($slider[1].innerText) - 1;
$dots.forEach((dot) => dot.classList.remove("on"));
$dots[currentSliderIndex % $dots.length].classList.add("on");
};
$prevBtn.addEventListener("click", () => {
handlePrevMove(1);
});
$nextBtn.addEventListener("click", () => {
handleNextMove(1);
});
$sliderDot.addEventListener("click", (e) => {
let destinationDot = e.target;
handlePagination(destinationDot);
});
handlePrevMove(1);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment