<div id="carousel">
<button id="prev-btn"><</button>
<button id="next-btn">></button>
<img id="image"/>
<div id="dots-container"></div>
</div>
#carousel {
border: 1px solid black;
width: 50%;
aspect-ratio: 3 / 2;
position: fixed;
left: 25%;
top: 200px;
}
#prev-btn {
position: absolute;
top: 46%;
left: 10px;
cursor: pointer;
}
#next-btn {
position: absolute;
top: 46%;
right: 10px;
curson: pointer;
}
img {
width: 100%;
height: 100%;
object-fit:cover;
object-position:center;
}
#dots-container {
text-align: center;
position: absolute;
bottom: 10px;
left: 50%;
transform: translate(-50%);
}
.dot {
width: 15px;
height: 15px;
border: 1px solid black;
border-radius: 50%;
margin: 0 3px;
background-color: rgba(0, 0, 0, 0.2);
cursor: pointer;
}
.dot.active {
background-color: rgba(0, 0, 0, 0.8);
}
/*
* https://frontendeval.com/questions/image-carousel
*
* Build an auto-playing image carousel
*/
const carousel = document.getElementById('carousel');
const image = document.getElementById("image");
const prevButton = document.getElementById('prev-btn');
const nextButton = document.getElementById('next-btn');
const dotsContainer = document.getElementById('dots-container');
let imageList;
let curIndex = 0;
let intervalId;
const showNextImage = () => {
dotsContainer.children[curIndex].classList.remove('active');
if (curIndex == imageList.length - 1) {
curIndex = 0;
} else {
curIndex++;
}
dotsContainer.children[curIndex].classList.add('active');
image.src = imageList[curIndex];
clearInterval(intervalId);
intervalId = setInterval(showNextImage, 3000);
};
const showPrevImage = () => {
dotsContainer.children[curIndex].classList.remove('active');
if (curIndex == 0) {
curIndex = imageList.length - 1;
} else {
curIndex--;
}
dotsContainer.children[curIndex].classList.add('active');
image.src = imageList[curIndex];
clearInterval(intervalId);
intervalId = setInterval(showNextImage, 3000);
};
const initialize = async () => {
const endpoint = "https://www.reddit.com/r/aww/top/.json?t=all";
try {
// fetch data
const response = await fetch(endpoint);
const jsonResponse = await response.json();
// initialize list
imageList = jsonResponse.data.children.filter((img) => {
return img.data.url_overridden_by_dest.includes('jpg');
}).map((img) => {
return img.data.url_overridden_by_dest;
});
// create dots
for (let i = 0; i < imageList.length; i++) {
let dot = document.createElement('button');
dot.classList.add('dot');
dot.id = 'dot' + i;
dotsContainer.appendChild(dot);
dot.addEventListener('click', () => {
clearInterval(intervalId);
dotsContainer.children[curIndex].classList.remove('active');
curIndex = i;
dotsContainer.children[curIndex].classList.add('active');
image.src = imageList[curIndex];
intervalId = setInterval(showNextImage, 3000);
});
}
// set first image as active
image.src = imageList[curIndex];
dotsContainer.children[curIndex].classList.add('active');
// start auto play
intervalId = setInterval(showNextImage, 3000);
} catch (error) {
console.error('Could not fetch data: ', error);
}
};
initialize();
prevButton.addEventListener('click', showPrevImage);
nextButton.addEventListener('click', showNextImage);
View Compiled
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.