英文:
CSS/JS Slider Animation Loop with Sequential Slide Positions
问题
我想实现一个CSS/JS滑块,应该执行以下操作:
- 应该有2个或更多个div
- 应该在加载时显示第一个div 3秒钟,然后第一个div 应该被第二个替换,第二个被第三个替换,依此类推...
- 动画必须按顺序出现(右,下,左,上...)
- 动画应该循环播放
- 每个div必须显示3秒,然后显示下一张幻灯片
我尝试了以下代码:https://codesandbox.io/s/nostalgic-dewdney-lnz8kr?file=/index.html
我对代码有一些问题,比如它不循环播放,每张幻灯片的持续时间不同,我在哪里出错了?
英文:
I want to implement a CSS/JS slider that should do the following
- There should be 2 or more div
- It should show the first div for 3 seconds on load, then the first div should get replaced with second, second with third and so on...
- Animation must come in a sequence (right, bottom, left, top...)
- Animation should be played in loop
- Each div must show for 3 seconds and then show the next slide
I have tried the following code: https://codesandbox.io/s/nostalgic-dewdney-lnz8kr?file=/index.html
I have few issues with the code such as, it does not play in loop, and there is a difference in duration of each slide, where am I going wrong here?
答案1
得分: 1
我会更改类。类似这样的:
document.querySelectorAll('.slider-container').forEach(slider => {
const delay = Number(slider.dataset.delay) || 0;
const transitionDuration = Number(slider.dataset.transitionDuration) || 400;
let autoplayDelay = Number(slider.dataset.autoplayDelay) || 3000;
if (autoplayDelay - transitionDuration < 100) {
autoplayDelay = transitionDuration + 100;
}
const classes = ['from-right', 'from-bottom', 'from-left', 'from-top'];
let nextClassIndex = -1;
setTimeout(() => {
setTimeout(() => {
slide();
setInterval(slide, autoplayDelay);
}, autoplayDelay);
}, delay);
function slide() {
const activeSlide = slider.querySelector('.slide.active');
const nextSlide = activeSlide.nextElementSibling ?? slider.querySelector('.slide:first-child');
const animationClass = classes[nextClassIndex + 1];
nextClassIndex++;
if (nextClassIndex === classes.length - 1) {
nextClassIndex = -1;
}
classes.map(className => activeSlide.classList.remove(className));
activeSlide.style.removeProperty('transition-duration');
activeSlide.style.removeProperty('z-index');
nextSlide.classList.add(animationClass);
nextSlide.style.transitionDuration = transitionDuration + 'ms';
nextSlide.style.zIndex = 6;
nextSlide.classList.add('active');
setTimeout(() => nextSlide.classList.add('animated'), 100);
setTimeout(() => activeSlide.classList.remove('active', 'animated'), transitionDuration + 100);
}
})
.slider-container {
position: relative;
width: 200px;
height: 200px;
overflow: hidden;
}
.slide {
position: absolute;
inset: 0;
transition-property: transform;
will-change: transform;
display: none;
}
.slide.from-right {
transform: translateX(100%);
}
.slide.from-left {
transform: translateX(-100%);
}
.slide.from-top {
transform: translateY(-100%);
}
.slide.from-bottom {
transform: translateY(100%);
}
.slide.animated {
transform: none;
}
.slide.active {
display: block;
}
<div class="slider-container">
<div class="slide active" style="background-color: red;">0</div>
<div class="slide" style="background-color: blue;">1</div>
</div>
<div
class="slider-container"
data-delay="2000"
data-transition-duration="800"
>
<div class="slide active" style="background-color: red;">0</div>
<div class="slide" style="background-color: blue;">1</div>
<div class="slide" style="background-color: green;">2</div>
<div class="slide" style="background-color: yellow;">3</div>
<div class="slide" style="background-color: brown;">4</div>
<div class="slide" style="background-color: red;">5</div>
<div class="slide" style="background-color: blue;">6</div>
<div class="slide" style="background-color: green;">7</div>
</div>
英文:
I would change classes. Something like this:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
document.querySelectorAll('.slider-container').forEach(slider => {
const delay = Number(slider.dataset.delay) || 0;
const transitionDuration = Number(slider.dataset.transitionDuration) || 400;
let autoplayDelay = Number(slider.dataset.autoplayDelay) || 3000;
if (autoplayDelay - transitionDuration < 100) {
autoplayDelay = transitionDuration + 100;
}
const classes = ['from-right', 'from-bottom', 'from-left', 'from-top'];
let nextClassIndex = -1;
setTimeout(() => {
setTimeout(() => {
slide();
setInterval(slide, autoplayDelay);
}, autoplayDelay)
}, delay);
function slide() {
const activeSlide = slider.querySelector('.slide.active');
const nextSlide = activeSlide.nextElementSibling ?? slider.querySelector('.slide:first-child');
const animationClass = classes[nextClassIndex + 1];
nextClassIndex++;
if (nextClassIndex === classes.length - 1) {
nextClassIndex = -1;
}
classes.map(className => activeSlide.classList.remove(className));
activeSlide.style.removeProperty('transition-duration');
activeSlide.style.removeProperty('z-index');
nextSlide.classList.add(animationClass);
nextSlide.style.transitionDuration = transitionDuration + 'ms';
nextSlide.style.zIndex = 6;
nextSlide.classList.add('active');
setTimeout(() => nextSlide.classList.add('animated'), 100)
setTimeout(() => activeSlide.classList.remove('active', 'animated'), transitionDuration + 100 );
}
})
<!-- language: lang-css -->
.slider-container {
position: relative;
width: 200px;
height: 200px;
overflow: hidden;
}
.slide {
position: absolute;
inset:0;
transition-property: transform;
will-change: transform;
display:none;
}
.slide.from-right {
transform: translateX(100%);
}
.slide.from-left {
transform: translateX(-100%);
}
.slide.from-top {
transform: translateY(-100%);
}
.slide.from-bottom {
transform: translateY(100%);
}
.slide.animated {
transform: none;
}
.slide.active {
display: block
}
<!-- language: lang-html -->
<div class="slider-container">
<div class="slide active" style="background-color: red;">0</div>
<div class="slide" style="background-color: blue;">1</div>
</div>
<div
class="slider-container"
data-delay="2000"
data-transition-duration="800"
>
<div class="slide active" style="background-color: red;">0</div>
<div class="slide" style="background-color: blue;">1</div>
<div class="slide" style="background-color: green;">2</div>
<div class="slide" style="background-color: yellow;">3</div>
<div class="slide" style="background-color: brown;">4</div>
<div class="slide" style="background-color: red;">5</div>
<div class="slide" style="background-color: blue;">6</div>
<div class="slide" style="background-color: green;">7</div>
</div>
<!-- end snippet -->
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论