JSFiddle - React, Tailwind, and code Playground
HTML
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css" integrity="sha512-DTOQO9RWCH3ppGqcWaEA1BIZOC6xxalwEsw9c2QQeAIftl+Vegovlnee1c9QX4TctnWMn13TZye+giMm8e2LwA==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<h1 style="text-align: center; position: absolute; width: 100%; z-index: 1; color: #ccc;">JavaScript 系列三:練習7 ──
carousel 輪播元件
</h1>
<div class="carousel">
<img src="https://picsum.photos/id/38/1500/900" alt="" class="">
<img src="https://picsum.photos/id/56/1500/900" alt="" class="">
<img src="https://picsum.photos/id/101/1500/900" alt="" class="">
<img src="https://picsum.photos/id/103/1500/900" alt="" class="">
<img src="https://picsum.photos/id/84/1500/900" alt="" class="">
<button class="slide-btn" id="slidePre" onclick="swipeSlide(-1)"><i class="fa-solid fa-chevron-left"></i></button>
<button class="slide-btn" id="slideNext" onclick="swipeSlide(+1)"><i class="fa-solid fa-chevron-right"></i></button>
<div class="pages">
<div class="bar"></div>
<div class="bar"></div>
<div class="bar"></div>
<div class="bar"></div>
<div class="bar"></div>
</div>
</div>
CSS
* {
padding: 0;
margin: 0;
}
.carousel {
width: 100%;
height: 100vh;
position: relative;
overflow: hidden;
}
.carousel .slide-btn {
width: 50px;
height: 50px;
line-height: 50px;
font-size: 24px;
border-radius: 50%;
border: none;
cursor: pointer;
overflow: hidden;
color: rgba(200, 200, 200, 0.3);
background-color: transparent;
transition: 0.3s;
position: absolute;
top: 50%;
transform: translateY(-50%);
}
.carousel .slide-btn#slidePre {
left: 20px;
}
.carousel .slide-btn#slideNext {
right: 20px;
}
.carousel .slide-btn:hover {
color: rgba(10, 10, 10, 1);
background-color: rgba(240, 240, 240, 0.5);
}
.carousel img {
display: block;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: cover;
object-position: center center;
opacity: 0;
transition: 0.5s;
}
.carousel img.active {
opacity: 1;
}
.pages {
position: absolute;
bottom: 0;
width: 100%;
height: 30px;
text-align: center;
font-size: 0;
}
.pages .bar {
display: inline-block;
width: 70px;
height: 100%;
margin: 0 10px;
position: relative;
cursor: pointer;
}
.pages .bar::after {
position: absolute;
content: "";
display: block;
left: 10px;
right: 10px;
height: 5px;
top: 0;
bottom: 0;
margin: auto;
border-radius: 5px;
background-color: rgba(240, 240, 240, 0.3);
transition: 0.5s;
}
.pages .bar.active::after {
background-color: rgba(240, 240, 240, 0.7);
}
JavaScript
const imgCount = document.querySelectorAll(".carousel img").length;
const imgMaxIndex = imgCount - 1;
let currentIndex = 0;
let imgs = document.querySelectorAll(".carousel img");
let bars = document.querySelectorAll(".carousel .bar");
let timeOutId;
for (let i = 0; i < imgCount; i++) {
bars[i].addEventListener("click", function() {
currentIndex = i;
showSlide();
});
}
function showSlide() {
clearTimeout(timeOutId);
for (let i = 0; i < imgCount; i++) {
bars[i].classList.remove("active");
imgs[i].classList.remove("active");
}
bars[currentIndex].classList.add("active");
imgs[currentIndex].classList.add("active");
timeOutId = setTimeout(function() {
swipeSlide(1);
}, 5000);
}
function swipeSlide(num) {
if (currentIndex + num < 0) {
currentIndex = imgMaxIndex;
} else if (currentIndex + num > imgMaxIndex) {
currentIndex = 0;
} else {
currentIndex += num;
}
showSlide();
}
showSlide();