admin管理员组文章数量:1125046
I've implemented a basic image carousel (similar to this example). However, I'm encountering an issue with the transition when looping from the first slide to the last, or vice-versa. Instead of smoothly transitioning to the adjacent slide, all images shift, creating a jarring visual effect. I want the transition to behave as if the carousel were a continuous loop, only showing the single slide change.
Here are my code.
const slidesContainer = document.getElementById("slides-container");
const dotsContainer = document.getElementById("dots-container");
const prevButton = document.getElementById("slide-arrow-prev");
const nextButton = document.getElementById("slide-arrow-next");
const images = ["img1", "img2", "img3"];
let slideIndex = 1;
document.addEventListener("DOMContentLoaded", () => {
generateImages(images);
setEventForButton(prevButton);
setEventForButton(nextButton);
});
// Generate images and dots
const generateImages = (imageToGenerate) => {
imageToGenerate.forEach((image, index) => {
// Generate images
const slideComponent = document.createElement("li");
slideComponent.classList.add("slide");
slideComponent.innerHTML = `
<img src="=${image}.jpg" alt="Image ${index + 1}" />
`;
slidesContainer.appendChild(slideComponent);
// Generate dots
const dotComponent = document.createElement("li");
dotComponent.classList.add("dot");
if (index === 0) dotComponent.classList.add("active");
dotComponent.addEventListener("click", () => {
showSlide(index + 1);
});
dotsContainer.appendChild(dotComponent);
});
};
// Set event for next button
const setEventForButton = (button) => {
button.addEventListener("click", () => {
if (button.id === "slide-arrow-prev") showSlide(slideIndex > 1 ? slideIndex - 1 : images.length);
else showSlide(slideIndex < images.length ? slideIndex + 1 : 1);
});
};
// Set slideshow
const showSlide = (n) => {
const slides = document.querySelectorAll(".slide");
const dots = document.querySelectorAll(".dot");
const slideWidth = slides[0].clientWidth;
slidesContainer.scrollLeft = slideWidth * (n - 1);
dots.forEach((dot) => dot.classList.remove("active"));
dots[n - 1].classList.add("active");
slideIndex = n;
};
* {
box-sizing: border-box;
}
body {
max-width: 1440px;
margin: auto;
}
.slider-wrapper {
margin: 1rem;
position: relative;
overflow: hidden;
}
.slides-container {
height: calc(100vh - 2rem);
width: 100%;
display: flex;
scroll-behavior: smooth;
overflow: hidden;
list-style: none;
margin: 0;
padding: 0;
}
.slide-arrow {
position: absolute;
display: flex;
top: 0;
bottom: 0;
margin: auto;
height: 4rem;
background-color: white;
border: none;
width: 2rem;
font-size: 3rem;
padding: 0;
cursor: pointer;
opacity: 0.5;
transition: opacity 100ms;
}
.slide-arrow:hover,
.slide-arrow:focus {
opacity: 1;
}
#slide-arrow-prev {
left: 0;
padding-left: 0.25rem;
border-radius: 0 2rem 2rem 0;
}
#slide-arrow-next {
right: 0;
padding-left: 0.75rem;
border-radius: 2rem 0 0 2rem;
}
.slide {
width: 100%;
height: 100%;
flex: 1 0 100%;
}
.slide img {
width: 100%;
height: 100%;
object-fit: contain;
}
.dots-container {
position: absolute;
top: 76%;
left: 49%;
right: auto;
transform: translateX(-50%);
display: flex;
}
.dot {
cursor: pointer;
display: inline-block;
width: 0.8rem;
height: 0.8rem;
margin: 0 2px;
border-radius: 50%;
background-color: gray;
transition: background_color 0.6s ease;
}
.active,
.dot:hover {
background-color: black;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Exercise 2</title>
<link rel="stylesheet" href="./styles2.css" />
</head>
<body>
<section class="slider-wrapper">
<button class="slide-arrow" id="slide-arrow-prev">‹</button>
<button class="slide-arrow" id="slide-arrow-next">›</button>
<!-- Generate images -->
<ul class="slides-container" id="slides-container"></ul>
<!-- Generate dots -->
<ul class="dots-container" id="dots-container"></ul>
</section>
<script src="./index2.js"></script>
</body>
</html>
I've implemented a basic image carousel (similar to this example). However, I'm encountering an issue with the transition when looping from the first slide to the last, or vice-versa. Instead of smoothly transitioning to the adjacent slide, all images shift, creating a jarring visual effect. I want the transition to behave as if the carousel were a continuous loop, only showing the single slide change.
Here are my code.
const slidesContainer = document.getElementById("slides-container");
const dotsContainer = document.getElementById("dots-container");
const prevButton = document.getElementById("slide-arrow-prev");
const nextButton = document.getElementById("slide-arrow-next");
const images = ["img1", "img2", "img3"];
let slideIndex = 1;
document.addEventListener("DOMContentLoaded", () => {
generateImages(images);
setEventForButton(prevButton);
setEventForButton(nextButton);
});
// Generate images and dots
const generateImages = (imageToGenerate) => {
imageToGenerate.forEach((image, index) => {
// Generate images
const slideComponent = document.createElement("li");
slideComponent.classList.add("slide");
slideComponent.innerHTML = `
<img src="https://placehold.co/600x400?text=${image}.jpg" alt="Image ${index + 1}" />
`;
slidesContainer.appendChild(slideComponent);
// Generate dots
const dotComponent = document.createElement("li");
dotComponent.classList.add("dot");
if (index === 0) dotComponent.classList.add("active");
dotComponent.addEventListener("click", () => {
showSlide(index + 1);
});
dotsContainer.appendChild(dotComponent);
});
};
// Set event for next button
const setEventForButton = (button) => {
button.addEventListener("click", () => {
if (button.id === "slide-arrow-prev") showSlide(slideIndex > 1 ? slideIndex - 1 : images.length);
else showSlide(slideIndex < images.length ? slideIndex + 1 : 1);
});
};
// Set slideshow
const showSlide = (n) => {
const slides = document.querySelectorAll(".slide");
const dots = document.querySelectorAll(".dot");
const slideWidth = slides[0].clientWidth;
slidesContainer.scrollLeft = slideWidth * (n - 1);
dots.forEach((dot) => dot.classList.remove("active"));
dots[n - 1].classList.add("active");
slideIndex = n;
};
* {
box-sizing: border-box;
}
body {
max-width: 1440px;
margin: auto;
}
.slider-wrapper {
margin: 1rem;
position: relative;
overflow: hidden;
}
.slides-container {
height: calc(100vh - 2rem);
width: 100%;
display: flex;
scroll-behavior: smooth;
overflow: hidden;
list-style: none;
margin: 0;
padding: 0;
}
.slide-arrow {
position: absolute;
display: flex;
top: 0;
bottom: 0;
margin: auto;
height: 4rem;
background-color: white;
border: none;
width: 2rem;
font-size: 3rem;
padding: 0;
cursor: pointer;
opacity: 0.5;
transition: opacity 100ms;
}
.slide-arrow:hover,
.slide-arrow:focus {
opacity: 1;
}
#slide-arrow-prev {
left: 0;
padding-left: 0.25rem;
border-radius: 0 2rem 2rem 0;
}
#slide-arrow-next {
right: 0;
padding-left: 0.75rem;
border-radius: 2rem 0 0 2rem;
}
.slide {
width: 100%;
height: 100%;
flex: 1 0 100%;
}
.slide img {
width: 100%;
height: 100%;
object-fit: contain;
}
.dots-container {
position: absolute;
top: 76%;
left: 49%;
right: auto;
transform: translateX(-50%);
display: flex;
}
.dot {
cursor: pointer;
display: inline-block;
width: 0.8rem;
height: 0.8rem;
margin: 0 2px;
border-radius: 50%;
background-color: gray;
transition: background_color 0.6s ease;
}
.active,
.dot:hover {
background-color: black;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Exercise 2</title>
<link rel="stylesheet" href="./styles2.css" />
</head>
<body>
<section class="slider-wrapper">
<button class="slide-arrow" id="slide-arrow-prev">‹</button>
<button class="slide-arrow" id="slide-arrow-next">›</button>
<!-- Generate images -->
<ul class="slides-container" id="slides-container"></ul>
<!-- Generate dots -->
<ul class="dots-container" id="dots-container"></ul>
</section>
<script src="./index2.js"></script>
</body>
</html>
Share
Improve this question
edited 2 days ago
mplungjan
177k28 gold badges180 silver badges240 bronze badges
asked 2 days ago
Đông NguyễnĐông Nguyễn
32 bronze badges
1
- I suggest you clone the first and last image and then use mod to keep the index inside the range - alternatively move the first visible image to the end after scroll – mplungjan Commented 2 days ago
1 Answer
Reset to default 0
var doslide=2;
var mousepostmp;
function autoslideleft(){
setInterval(function(){
if(doslide){
var arrel=document.getElementsByClassName("slideboxesspan");
var len0=arrel.length;
var x=arrel[0].offsetWidth;
arrel[0].style.marginLeft=(x*-1)+"px";
setTimeout(function(){
arrel[0].style.marginLeft="0px";
document.getElementById("slideholderid").appendChild(arrel[0]);
for(var t=0;t<len0;t++){arrel[t].style.marginLeft="8px";}
},400);
}
},2000);
}
function slideleft(){
var arrel=document.getElementsByClassName("slideboxesspan");
var len0=arrel.length;
var x=arrel[0].offsetWidth;
arrel[0].style.marginLeft=(x*-1)+"px";
setTimeout(function(){
arrel[0].style.marginLeft="0px";
document.getElementById("slideholderid").appendChild(arrel[0]);
for(var t=0;t<len0;t++){arrel[t].style.marginLeft="8px";}
},400);
}
function slideright(){
var arrel=document.getElementsByClassName("slideboxesspan");
var containing=document.getElementById("slideholderid");
var len0=arrel.length;
var x=arrel[0].offsetWidth;
var newel="<span class='slideboxesspan slideSize' style='transition:0.4s;margin-left:"+(x*-1)+"px;'>"+arrel[len0-1].innerHTML+"</span>";
containing.removeChild(arrel[len0-1]);
containing.innerHTML=newel+containing.innerHTML;
var arrel=document.getElementsByClassName("slideboxesspan");
setTimeout(function(){arrel[0].style.marginLeft=(0)+"px";
for(var t=0;t<len0;t++){arrel[t].style.marginLeft="8px";}
},50);
}
function slideact(st){
doslide=st;
}
function startonload(){
//autoslideleft();
}
body{overflow-x:hidden;-webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none;}
.slideholder{display:inline-flex;overflow:hidden;}
.slideboxesspan{transition:0.4s;margin-left:8px;}
.slideSize{width:40vw;height:40vw;/*silde size*/}
.imgSlide{width:100%;height:100%;}
<body onload="startonload();">
<div align="center">
<div id="slideholderid" align="center" class="slideholder slideSize">
<span class="slideboxesspan slideSize">
<div align="center" class="slideboxes slideSize">
<img src="3.jpg" class="imgSlide"/>
</div>
</span>
<span class="slideboxesspan">
<div align="center" class="slideboxes slideSize">
<img src="4.jpg" class="imgSlide"/>
</div>
</span>
<span class="slideboxesspan">
<div align="center" class="slideboxes slideSize">
<img src="5.jpg" class="imgSlide"/>
</div>
</span>
<span class="slideboxesspan">
<div align="center" class="slideboxes slideSize">
<img src="3.jpg" class="imgSlide"/>
</div>
</span>
<span class="slideboxesspan">
<div align="center" class="slideboxes slideSize">
<img src="4.jpg" class="imgSlide"/>
</div>
</span>
<span class="slideboxesspan">
<div align="center" class="slideboxes slideSize">
<img src="5.jpg" class="imgSlide"/>
</div>
</span>
</div>
</div>
<input type="button" value="<" onclick="slideleft();" style="background-color:red;"/>
<input type="button" value=">" onclick="slideright();" style="background-color:red;"/>
</body>
本文标签:
版权声明:本文标题:javascript - How can I change the animation for first image and last image when creating a Carousel slide by HTML, CSS and pure 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736655627a1946245.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论