使用纯JavaScript创建图像轮播器

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

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(&quot;.div-container&quot;)
const nextBtn = document.querySelector(&quot;.next&quot;)
const prevBtn = document.querySelector(&quot;.previous&quot;)
let currentIndex = 0;

const nextSlide = () =&gt; {
  const slides = document.getElementsByClassName(&quot;slide&quot;)
  for (let i = 0; i &lt; slides.length; i++) {
    slides[i].style.display = &quot;none&quot;
  }
  currentIndex++
  if (currentIndex &gt; slides.length) {
    currentIndex = 1
  }
  slides[currentIndex - 1].style.display = &quot;block&quot;
}

nextSlide()

const prevSlide = () =&gt; {
  const slides = document.getElementsByClassName(&quot;slide&quot;)
  for (let i = 0; i &lt; slides.length; i++) {
    slides[i].style.display = &quot;none&quot;
  }
  currentIndex--
  slides[currentIndex - 1].style.display = &quot;block&quot;
}

nextBtn.addEventListener(&quot;click&quot;, () =&gt; {
  nextSlide()
})

prevBtn.addEventListener(&quot;click&quot;, () =&gt; {
  prevSlide()
})

<!-- language: lang-css -->

.div-container {
  display: flex;
  justify-content: center;
  max-width: 1000px;
}

.slide {
  display: none;
}

.image {
  width: 300px;
}

<!-- language: lang-html -->

&lt;body&gt;
  &lt;div class=&quot;div-container&quot;&gt;
    &lt;button class=&quot;previous&quot;&gt;Previous&lt;/button&gt;
    &lt;div class=&quot;slide fade&quot;&gt;
      &lt;img src=&quot;https://i.redd.it/z7myrlhfhxr31.jpg&quot; alt=&quot;windows xp autumn&quot; class=&quot;image&quot;&gt;
    &lt;/div&gt;
    &lt;div class=&quot;slide fade&quot;&gt;
      &lt;img src=&quot;https://www.newegg.com/insider/wp-content/uploads/windows_xp_bliss-wide.jpg&quot; alt=&quot;windows xp bliss&quot; class=&quot;image&quot;&gt;
    &lt;/div&gt;
    &lt;div class=&quot;slide fade&quot;&gt;
      &lt;img src=&quot;https://i0.wp.com/tjkelly.com/wp-content/uploads/windows-xp-desktop-background-wallpaper-follow-800x600.jpg?ssl=1&quot; alt=&quot;windows xp fishy&quot; class=&quot;image&quot;&gt;
    &lt;/div&gt;
    &lt;button class=&quot;next&quot;&gt;Next&lt;/button&gt;
  &lt;/div&gt;
&lt;/body&gt;

<!-- 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添加到当前值来计算一个新的currentIndexinc可以是-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(&quot;.div-container&quot;)
const nextBtn = document.querySelector(&quot;.next&quot;)
const prevBtn = document.querySelector(&quot;.previous&quot;)
let currentIndex = 0;

const nextSlide = (inc) =&gt; {
  const slides = document.getElementsByClassName(&quot;slide&quot;)
  for (let i = 0; i &lt; slides.length; i++) {
    slides[i].style.display = &quot;none&quot;
  }
  currentIndex=(currentIndex+slides.length+inc)%slides.length;
  slides[currentIndex].style.display = &quot;block&quot;
}

nextSlide(0)

nextBtn.addEventListener(&quot;click&quot;, () =&gt; {
  nextSlide(1)
})

prevBtn.addEventListener(&quot;click&quot;, () =&gt; {
  nextSlide(-1)
})

<!-- language: lang-css -->

.div-container {
  display: flex;
  justify-content: center;
  max-width: 1000px;
}

.slide {
  display: none;
}

.image {
  width: 300px;
}

<!-- language: lang-html -->

&lt;body&gt;
  &lt;div class=&quot;div-container&quot;&gt;
    &lt;button class=&quot;previous&quot;&gt;Previous&lt;/button&gt;
    &lt;div class=&quot;slide fade&quot;&gt;
      &lt;img src=&quot;https://i.redd.it/z7myrlhfhxr31.jpg&quot; alt=&quot;windows xp autumn&quot; class=&quot;image&quot;&gt;
    &lt;/div&gt;
    &lt;div class=&quot;slide fade&quot;&gt;
      &lt;img src=&quot;https://www.newegg.com/insider/wp-content/uploads/windows_xp_bliss-wide.jpg&quot; alt=&quot;windows xp bliss&quot; class=&quot;image&quot;&gt;
    &lt;/div&gt;
    &lt;div class=&quot;slide fade&quot;&gt;
      &lt;img src=&quot;https://i0.wp.com/tjkelly.com/wp-content/uploads/windows-xp-desktop-background-wallpaper-follow-800x600.jpg?ssl=1&quot; alt=&quot;windows xp fishy&quot; class=&quot;image&quot;&gt;
    &lt;/div&gt;
    &lt;button class=&quot;next&quot;&gt;Next&lt;/button&gt;
  &lt;/div&gt;
&lt;/body&gt;

<!-- 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
}

huangapple
  • 本文由 发表于 2023年2月27日 12:02:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/75576683.html