Here is a a demo application code to show images in a carousel. It works well with static images. But I want to add images to the carousel dynamically on a button click.
I added images on a button click, and it adds it in the container, which I can see if I debug the page using the browser’s Developer Tools. But the image is not shown in the carousel.
document.addEventListener("DOMContentLoaded", function() {
let carousel = document.querySelector(".carousel");
let items = carousel.querySelectorAll(".item");
// Function to show a specific item
function showItem(index) {
items.forEach((item, idx) => {
item.classList.remove("active");
if (idx === index) {
item.classList.add("active");
}
});
}
// Event listeners for buttons
document.querySelector(".prev").addEventListener("click", () => {
let index = [...items].findIndex((item) =>
item.classList.contains("active")
);
showItem((index - 1 + items.length) % items.length);
});
document.querySelector(".next").addEventListener("click", () => {
let index = [...items].findIndex((item) =>
item.classList.contains("active")
);
showItem((index + 1) % items.length);
});
});
//I tried the following function:
function buttonClicked() {
const carouselContainer = document.querySelector('.carousel');
// Create the carousel item
const carouselItemContainer = document.createElement('div');
carouselItemContainer.classList.add('item');
// Create image element
const imageElement = document.createElement('img');
imageElement.src = "image URL";
imageElement.alt = "test image";
imageElement.classList.add("active");
// Add a title below the image
const imageTitle = document.createElement('p');
imageTitle.textContent = "title of test image";
imageTitle.classList.add('caption');
carouselItemContainer.appendChild(imageElement);
carouselItemContainer.appendChild(imageTitle);
carouselContainer.appendChild(carouselItemContainer);
}
body {
min-height: 100dvh;
display: flex;
align-items: center;
font-family: "Satoshi", sans-serif;
font-size: var(--lx-text-01);
font-weight: 500;
color: #ffffe6;
background-color: #10100e;
}
.carousel-container {
width: 80%;
margin: auto;
position: relative;
display: flex;
flex-direction: column;
gap: var(--lx-gap);
.carousel {
aspect-ratio: 16/9;
width: 100%;
position: relative;
overflow: hidden;
.item {
opacity: 0;
width: 100%;
height: 100%;
display: none;
transition: opacity 0.5s ease-in-out;
img {
width: 100%;
height: 100%;
object-fit: cover;
object-position: center;
}
.caption {
width: 100%;
padding: var(--lx-space-01);
position: absolute;
bottom: 0;
text-transform: uppercase;
text-align: center;
font-size: 12px;
background-color: rgba(0, 0, 0, 0.5);
}
&.active {
opacity: 1;
display: block;
}
}
}
.btn {
padding: 1em 2em;
position: absolute;
transform: translateY(-50%);
top: 50%;
outline: none;
border: none;
cursor: pointer;
text-transform: uppercase;
font-size: 12px;
font-weight: 900;
color: #10100e;
background-color: #ffffe6;
transition: transform 0.2s ease-in-out;
&:active,
&:focus {
transform: translateY(-50%) scale(0.9);
}
&:hover {
transform: translateY(-50%) scale(0.96);
}
}
.prev {
left: -5%;
}
.next {
right: -5%;
}
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>Image Slider</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" />
<link rel="stylesheet" href="style - copy.css" />
<script src="script - copy.js"></script>
</head>
<body>
<main class="carousel-container">
<div class="carousel">
<div class="item active">
<img src="https://images.unsplash.com/photo-1457732815361-daa98277e9c8?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1350&q=80" alt="Image 1" />
<p class="caption">Caption for Image 1</p>
</div>
<div class="item">
<img src="https://images.unsplash.com/photo-1500206329404-5057e0aefa48?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1355&q=80" alt="Image 2" />
<p class="caption">Caption for Image 2</p>
</div>
<div class="item">
<img src="https://images.unsplash.com/photo-1502239608882-93b729c6af43?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1350&q=80" alt="Image 3" />
<p class="caption">Caption for Image 3</p>
</div>
</div>
<button class="btn prev">Prev</button>
<button class="btn next">Next</button>
<div class="dots"></div>
</main>
</body>
</html>
It adds the image to the carousel container but the image is not displayed in the carousel.
2
Answers
Because the "next" and "prev" buttons in your code find the next image from the
items
array (rather than reading direct from the carousel container elemente each time), you need to ensure you re-initialiseitems
after you’ve added the new image, by reading the list of elements from the carousel container again.Once you add that step, your code works fine – demo:
Instead of relying on indexes and (global’ich) variables you can selecte the next/previous images based on the current active image. And when adding a new image you can just use that reference to display the image.