CSS/JS 滑块动画循环,具有顺序幻灯片位置

huangapple go评论97阅读模式
英文:

CSS/JS Slider Animation Loop with Sequential Slide Positions

问题

我想实现一个CSS/JS滑块,应该执行以下操作:

  1. 应该有2个或更多个div
  2. 应该在加载时显示第一个div 3秒钟,然后第一个div 应该被第二个替换,第二个被第三个替换,依此类推...
  3. 动画必须按顺序出现(右,下,左,上...)
  4. 动画应该循环播放
  5. 每个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

  1. There should be 2 or more div
  2. 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...
  3. Animation must come in a sequence (right, bottom, left, top...)
  4. Animation should be played in loop
  5. 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(&#39;.slider-container&#39;).forEach(slider =&gt; {
const delay = Number(slider.dataset.delay) || 0;
const transitionDuration = Number(slider.dataset.transitionDuration) || 400;
let autoplayDelay = Number(slider.dataset.autoplayDelay) || 3000;
if (autoplayDelay - transitionDuration &lt; 100) {
autoplayDelay = transitionDuration + 100;
}
const classes = [&#39;from-right&#39;, &#39;from-bottom&#39;, &#39;from-left&#39;, &#39;from-top&#39;];
let nextClassIndex = -1;
setTimeout(() =&gt; {
setTimeout(() =&gt; {
slide();
setInterval(slide, autoplayDelay);
}, autoplayDelay)
}, delay);
function slide() {
const activeSlide = slider.querySelector(&#39;.slide.active&#39;);
const nextSlide = activeSlide.nextElementSibling ?? slider.querySelector(&#39;.slide:first-child&#39;);
const animationClass = classes[nextClassIndex + 1];
nextClassIndex++;
if (nextClassIndex === classes.length - 1) {
nextClassIndex = -1;
}
classes.map(className =&gt; activeSlide.classList.remove(className));
activeSlide.style.removeProperty(&#39;transition-duration&#39;);
activeSlide.style.removeProperty(&#39;z-index&#39;);
nextSlide.classList.add(animationClass);
nextSlide.style.transitionDuration = transitionDuration + &#39;ms&#39;;
nextSlide.style.zIndex = 6;
nextSlide.classList.add(&#39;active&#39;);
setTimeout(() =&gt; nextSlide.classList.add(&#39;animated&#39;), 100)
setTimeout(() =&gt; activeSlide.classList.remove(&#39;active&#39;, &#39;animated&#39;), 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 -->

&lt;div class=&quot;slider-container&quot;&gt;
&lt;div class=&quot;slide active&quot; style=&quot;background-color: red;&quot;&gt;0&lt;/div&gt;
&lt;div class=&quot;slide&quot; style=&quot;background-color: blue;&quot;&gt;1&lt;/div&gt;
&lt;/div&gt;
&lt;div
class=&quot;slider-container&quot;
data-delay=&quot;2000&quot;
data-transition-duration=&quot;800&quot;
&gt;
&lt;div class=&quot;slide active&quot; style=&quot;background-color: red;&quot;&gt;0&lt;/div&gt;
&lt;div class=&quot;slide&quot; style=&quot;background-color: blue;&quot;&gt;1&lt;/div&gt;
&lt;div class=&quot;slide&quot; style=&quot;background-color: green;&quot;&gt;2&lt;/div&gt;
&lt;div class=&quot;slide&quot; style=&quot;background-color: yellow;&quot;&gt;3&lt;/div&gt;
&lt;div class=&quot;slide&quot; style=&quot;background-color: brown;&quot;&gt;4&lt;/div&gt;
&lt;div class=&quot;slide&quot; style=&quot;background-color: red;&quot;&gt;5&lt;/div&gt;
&lt;div class=&quot;slide&quot; style=&quot;background-color: blue;&quot;&gt;6&lt;/div&gt;
&lt;div class=&quot;slide&quot; style=&quot;background-color: green;&quot;&gt;7&lt;/div&gt;
&lt;/div&gt;

<!-- end snippet -->

huangapple
  • 本文由 发表于 2023年8月5日 16:15:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/76840717.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定