英文:
Creating an image carousel using vanilla JavaScript
问题
我想使用纯JavaScript和HTML创建一个图像轮播。我已经能够使用我拥有的逻辑移动到下一张幻灯片,但在处理上一张幻灯片功能时遇到了问题。在浏览下一张幻灯片时,幻灯片秀在最后重新开始显示第一张图片。我还希望在处理上一张幻灯片功能时,能够显示最后一张图片,而不是收到未捕获的类型错误。
我该如何实现这一点?
const container = document.querySelector(".div-container");
const nextBtn = document.querySelector(".next");
const prevBtn = document.querySelector(".previous");
let currentIndex = 0;
const nextSlide = () => {
const slides = document.getElementsByClassName("slide");
for (let i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
currentIndex++;
if (currentIndex > slides.length) {
currentIndex = 1;
}
slides[currentIndex - 1].style.display = "block";
}
nextSlide();
const prevSlide = () => {
const slides = document.getElementsByClassName("slide");
for (let i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
currentIndex--;
if (currentIndex < 1) {
currentIndex = slides.length;
}
slides[currentIndex - 1].style.display = "block";
}
nextBtn.addEventListener("click", () => {
nextSlide();
});
prevBtn.addEventListener("click", () => {
prevSlide();
});
.div-container {
display: flex;
justify-content: center;
max-width: 1000px;
}
.slide {
display: none;
}
.image {
width: 300px;
}
<body>
<div class="div-container">
<button class="previous">Previous</button>
<div class="slide fade">
<img src="https://i.redd.it/z7myrlhfhxr31.jpg" alt="windows xp autumn" class="image">
</div>
<div class="slide fade">
<img src="https://www.newegg.com/insider/wp-content/uploads/windows_xp_bliss-wide.jpg" alt="windows xp bliss" class="image">
</div>
<div class="slide fade">
<img src="https://i0.wp.com/tjkelly.com/wp-content/uploads/windows-xp-desktop-background-wallpaper-follow-800x600.jpg?ssl=1" alt="windows xp fishy" class="image">
</div>
<button class="next">Next</button>
</div>
</body>
英文:
I would like to create an image carousel using plain JavaScript and HTML. I have been able to move to the next slide with the logic I have but having trouble with the previous slide functionality. When going through the next slide the slideshow at the end restarts at the first picture. I would also like to have this behaviour with the previous slide functionality going to the last picture instead of receiving a Uncaught TypeError.
How can I achieve this ?
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
const container = document.querySelector(".div-container")
const nextBtn = document.querySelector(".next")
const prevBtn = document.querySelector(".previous")
let currentIndex = 0;
const nextSlide = () => {
const slides = document.getElementsByClassName("slide")
for (let i = 0; i < slides.length; i++) {
slides[i].style.display = "none"
}
currentIndex++
if (currentIndex > slides.length) {
currentIndex = 1
}
slides[currentIndex - 1].style.display = "block"
}
nextSlide()
const prevSlide = () => {
const slides = document.getElementsByClassName("slide")
for (let i = 0; i < slides.length; i++) {
slides[i].style.display = "none"
}
currentIndex--
slides[currentIndex - 1].style.display = "block"
}
nextBtn.addEventListener("click", () => {
nextSlide()
})
prevBtn.addEventListener("click", () => {
prevSlide()
})
<!-- language: lang-css -->
.div-container {
display: flex;
justify-content: center;
max-width: 1000px;
}
.slide {
display: none;
}
.image {
width: 300px;
}
<!-- language: lang-html -->
<body>
<div class="div-container">
<button class="previous">Previous</button>
<div class="slide fade">
<img src="https://i.redd.it/z7myrlhfhxr31.jpg" alt="windows xp autumn" class="image">
</div>
<div class="slide fade">
<img src="https://www.newegg.com/insider/wp-content/uploads/windows_xp_bliss-wide.jpg" alt="windows xp bliss" class="image">
</div>
<div class="slide fade">
<img src="https://i0.wp.com/tjkelly.com/wp-content/uploads/windows-xp-desktop-background-wallpaper-follow-800x600.jpg?ssl=1" alt="windows xp fishy" class="image">
</div>
<button class="next">Next</button>
</div>
</body>
<!-- end snippet -->
答案1
得分: 2
我尽量保持尽可能少的更改来修复您的代码。现在,我只使用一个函数来向前和向后移动,而不是两个分开的函数:
const container = document.querySelector(".div-container");
const nextBtn = document.querySelector(".next");
const prevBtn = document.querySelector(".previous");
let currentIndex = 0;
const nextSlide = (inc) => {
const slides = document.getElementsByClassName("slide");
for (let i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
currentIndex = (currentIndex + slides.length + inc) % slides.length;
slides[currentIndex].style display = "block";
}
nextSlide(0);
nextBtn.addEventListener("click", () => {
nextSlide(1);
});
prevBtn.addEventListener("click", () => {
nextSlide(-1);
});
.div-container {
display: flex;
justify-content: center;
max-width: 1000px;
}
.slide {
display: none;
}
.image {
width: 300px;
}
<body>
<div class="div-container">
<button class="previous">Previous</button>
<div class="slide fade">
<img src="https://i.redd.it/z7myrlhfhxr31.jpg" alt="windows xp autumn" class="image">
</div>
<div class="slide fade">
<img src="https://www.newegg.com/insider/wp-content/uploads/windows_xp_bliss-wide.jpg" alt="windows xp bliss" class="image">
</div>
<div class="slide fade">
<img src="https://i0.wp.com/tjkelly.com/wp-content/uploads/windows-xp-desktop-background-wallpaper-follow-800x600.jpg?ssl=1" alt="windows xp fishy" class="image">
</div>
<button class="next">Next</button>
</div>
</body>
操作的核心部分是以下表达式:
currentIndex = (currentIndex + slides.length + inc) % slides.length
它通过将inc
添加到当前值来计算一个新的currentIndex
。inc
可以是-1、0或1,结果值始终在0和slides.length-1
之间。
还有进一步改进的空间(简化代码和减少全局变量),但那是一个单独的问题。
英文:
I fixed your code with as little changes as possible. Instead of two separate functions I am now using just one for stepping forward and backward:
<!-- begin snippet: js hide: false console: true babel: null -->
<!-- language: lang-js -->
const container = document.querySelector(".div-container")
const nextBtn = document.querySelector(".next")
const prevBtn = document.querySelector(".previous")
let currentIndex = 0;
const nextSlide = (inc) => {
const slides = document.getElementsByClassName("slide")
for (let i = 0; i < slides.length; i++) {
slides[i].style.display = "none"
}
currentIndex=(currentIndex+slides.length+inc)%slides.length;
slides[currentIndex].style.display = "block"
}
nextSlide(0)
nextBtn.addEventListener("click", () => {
nextSlide(1)
})
prevBtn.addEventListener("click", () => {
nextSlide(-1)
})
<!-- language: lang-css -->
.div-container {
display: flex;
justify-content: center;
max-width: 1000px;
}
.slide {
display: none;
}
.image {
width: 300px;
}
<!-- language: lang-html -->
<body>
<div class="div-container">
<button class="previous">Previous</button>
<div class="slide fade">
<img src="https://i.redd.it/z7myrlhfhxr31.jpg" alt="windows xp autumn" class="image">
</div>
<div class="slide fade">
<img src="https://www.newegg.com/insider/wp-content/uploads/windows_xp_bliss-wide.jpg" alt="windows xp bliss" class="image">
</div>
<div class="slide fade">
<img src="https://i0.wp.com/tjkelly.com/wp-content/uploads/windows-xp-desktop-background-wallpaper-follow-800x600.jpg?ssl=1" alt="windows xp fishy" class="image">
</div>
<button class="next">Next</button>
</div>
</body>
<!-- end snippet -->
The central part of the operation is the expression
currentIndex=(currentIndex+slides.length+inc)%slides.length
It calculates a new currentIndex
by adding inc
to the current value. inc
can be -1, 0 or 1 and the resulting value will always be between 0 and slides.length-1
.
There is scope for further improvements (code simplification and reduction of global variables), but that is a separate issue.
答案2
得分: 0
只需在prevSlide函数中检查currentIndex是否为零,然后将其设置为slides.length:
currentIndex--
if (currentIndex === 0) {
currentIndex = slides.length
}
英文:
Just check in prevSlide function if currentIndex is zero and set it to slides.length:
currentIndex--
if (currentIndex === 0) {
currentIndex = slides.length
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论