分解 JavaScript 横幅滑块

Breaking down a JavaScript Banner Slider

我最近问了一个关于这个 'simple' 滑块的问题,我想更深入地研究一下。这是脚本:

var slides = document.querySelectorAll('#slides .slide');
var currentSlide = 0;
var slideInterval = setInterval(nextSlide, 2000);

function nextSlide(){
    slides[currentSlide].className = 'slide';
    currentSlide = (currentSlide+1)%slides.length;
    slides[currentSlide].className = 'slide showing';
}

所以我得到的是:

我看对了吗?

如果我是(我很确定我不是),该函数如何在没有循环函数的情况下循环遍历不同的幻灯片?

我认为我比我清楚地更了解这一点,所以任何解释都会有很大帮助。

谢谢。

实际上,函数nextSlide()本身并没有遍历图像,它只是将currentSlide的class设置为'slide'和下一张幻灯片(currentSlide+1)至 'slide showing'。 setInterval(nextSlide, 2000) 是使函数遍历所有图像的原因,此间隔每 2 秒调用一次 nextSlide 函数。

所以开始:

currentSlide 等于 0。 slideInterval 在 2 秒后调用 nextSlide()。 它将幻灯片 0 的 className 设置为 'slide' 并将 currentSlide 递增到 1。 然后它将幻灯片 1 的 className 设置为 'slide showing'。 现在 slideInterval 在 2 秒后调用 nextSlide() 但现在它以 currentSlide 等于 1 开始。

setInterval() 方法以指定的时间间隔(以毫秒为单位)调用函数或计算表达式。

setInterval() 方法将继续调用该函数,直到调用 clearInterval() 或 window 关闭。

所以 nextSlide{} 每两秒调用一次。

nextSlide() 必须包含递增滑块的逻辑

您关注得很好,但您跳过了重要的一行:setInterval(nextSlide, 2000)。此行的作用是每 2000 毫秒(2 秒)执行一次 nextSlide 函数。

nextSlide函数不是在定义的时候运行,而是在setInterval执行的时候。您的分析对于函数在第一次传递时的作用是正确的(当 currentSlide 设置为 0 时)。之后,currentSlide 将是 1, 2, ... 函数的三行执行以下操作:

  • 将当前幻灯片的 class 设置为 slide
  • 增加 currentSlide 变量(剩下的东西是当它超过可用幻灯片的末尾时循环回到 0
  • 将新当前幻灯片的 class 设置为 slide showing

这将每 2 秒发生一次。

代码的第一行将所有带有 .slide class 的元素放入 javascript 数组中。现在我们确实需要找到某种循环遍历所有幻灯片的方法。

setInterval(nextSlide, 2000); 行确保 nextSlide 函数在 2000 微秒后被调用。通常,在 nextSlide 函数中应该有另一个 setInterval(nextSlide, 2000); 调用,以确保在 2 秒内再次调用 nextSlide 函数。这样我们就创建了一种循环。也许在您的原始脚本的 nextSlide 函数中有一个 setInterval(nextSlide, 2000); 调用。这是绝对必要的。否则我们不会有一个循环。

nextSlide 函数隐藏当前幻灯片并显示下一张。在函数内部,计数器 currentSlide 递增。这就是导致循环的原因。

nextSlide函数里面有什么?

slides[currentSlide].className = 'slide'; 
// remove the showing class so the slide with the index 'currentSlide' no longer shows

currentSlide = (currentSlide+1);
// increment the counter so it points to the next slide

slides[currentSlide].className = 'slide showing'; 
// add the showing class to this slide, so this slide is now showing.

现在我们要补充一件事。当我们 运行 离开幻灯片时,我们必须确保我们的计数器 returns 到第一张幻灯片。我们为此使用 % 模运算符。当我们希望数字在达到某个值时 "wrap around" 时使用 Modular arithmetic。 (维基百科文章有一个很好的时钟示例)。

我们想给 currentSlide 计数器加 1,我们希望它环绕幻灯片总数(= 幻灯片数组的长度):

currentSlide = (currentSlide+1)%slides.length;

诀窍在于这一行:

currentSlide = (currentSlide+1) % slides.length;

因此,如果我们假设 slides.length 等于 3,那么 (currentSlide+1) % slides.length 在第三次计算为 0 并重新设置,就像这样...

1 % slides.length // 1
2 % slides.length // 2
3 % slides.length // 0

所以它看起来更像这样:

// Get the currentSlide and set the className to 'slide'
slides[currentSlide].className = 'slide';

// Set currentSlide to the next slide, i.e. 1, 2, or 0
currentSlide = (currentSlide+1)%slides.length;

/*
   currentSlide is technically the next slide at this point, so
   it's actually getting the next slide and setting the className
   to 'slide showing'. The next slide will be slide 0
   on the third time round.
*/
slides[currentSlide].className = 'slide showing';

以上代码每2秒执行一次,使用setInterval(nextSlide, 2000)

希望这是有道理的! :)