JavaScript 无限循环幻灯片有延迟?

IT技术 javascript loops
2021-01-26 19:27:52

如何在 JavaScript 中进行无限循环?我正在尝试制作幻灯片,我正在使用它,但无法循环播放。我什至无法让它循环两次。

我现在使用的代码是

window.onload = function start() {
    slide();
}
function slide() {
    var num = 0;
    for (num=0;num<=10;num++) {
        setTimeout("document.getElementById('container').style.marginLeft='-600px'",3000);
        setTimeout("document.getElementById('container').style.marginLeft='-1200px'",6000);
        setTimeout("document.getElementById('container').style.marginLeft='-1800px'",9000);
        setTimeout("document.getElementById('container').style.marginLeft='0px'",12000);
    }
}

如果没有 for 东西,它确实会通过一次。当我输入 for 时,它要么使 Firefox 锁定,要么只循环一次。我确信这是一件非常简单的事情,即使它必须循环 1,000,000 次或其他什么而不是无限,这对我来说也很好用。

另外,我不想使用 jQuery 或其他人创建的东西。我正在学习 JavaScript,这部分是为了帮助我学习,部分是因为我正在尝试制作尽可能多的基于 HTML5 的系统。

编辑:我认为它冻结的原因是因为它一次执行所有代码,然后将其存储在缓存或其他东西中。我想要它做的是经历一次,然后再次从顶部开始,这就是我一直认为循环的目的。在“批处理”(命令提示符)脚本中,这可以通过“ GOTO”命令来完成我不知道 JS 中是否有等价物,但这确实是我的目标。

6个回答

正确的方法是使用单个计时器。使用setInterval,您可以按如下方式实现您想要的:

window.onload = function start() {
    slide();
}
function slide() {
    var num = 0, style = document.getElementById('container').style;
    window.setInterval(function () {
        // increase by num 1, reset to 0 at 4
        num = (num + 1) % 4;

        // -600 * 1 = -600, -600 * 2 = -1200, etc 
        style.marginLeft = (-600 * num) + "px"; 
    }, 3000); // repeat forever, polling every 3 seconds
}
这有效,谢谢:) 这实际上是我最初尝试做的,但无法弄清楚如何添加到 marginLeft。编辑:这个答案也正是我想要的,因为如果我想添加 20 张幻灯片,它只需要一次快速编辑。谢谢,这太棒了。
2021-03-13 19:27:52
@Andy 这看起来和我的很相似,主要的例外是(我认为)你的写得更漂亮:)
2021-03-14 19:27:52
@Rev:很乐意提供帮助,这里有很多令人困惑的答案,所以我认为加入我的解决方案是个好主意:-)
2021-03-20 19:27:52
惊人的。我觉得有点玩这个,所以加了一点:jsfiddle.net/entropo/fy3vQ
2021-03-28 19:27:52
@Andy 我不怪你,我自己一直认为我必须在提供的混乱答案中错过一个答案(就像我们的一样)。我看了好几遍,以为我错过了它,但意识到实际上,几乎每个答案都是错误的。我确实看到你选择了setInterval路线,所以你的答案是不同的 :)
2021-04-07 19:27:52

你不想要while(true),那会锁定你的系统。

你想要的是一个超时,它自己设置一个超时,像这样:

function start() {
  // your code here
  setTimeout(start, 3000);
}

// boot up the first call
start();

这是一个不错的,整洁的解决方案:(另请参阅现场演示 ->

window.onload = function start() {
    slide();
}

function slide() {
    var currMarg = 0,
        contStyle = document.getElementById('container').style;
    setInterval(function() {
        currMarg = currMarg == 1800 ? 0 : currMarg + 600;
        contStyle.marginLeft = '-' + currMarg + 'px';
    }, 3000);
}

既然您正在努力学习,请允许我解释一下这是如何工作的。

首先我们声明两个变量:currMargcontStylecurrMarg是一个整数,我们将使用它来跟踪/更新容器应具有的左边距。我们在实际更新函数之外(在闭包中声明它,以便它可以不断更新/访问而不会丢失其值。 contStyle只是一个方便的变量,它使我们可以访问容器样式,而无需在每个间隔上定位元素。

接下来,我们将使用setInterval建立一个应每 3 秒调用一次的函数,直到我们告诉它停止(这是无限循环,不会冻结浏览器)。它的工作原理与 完全一样setTimeout,只是它会无限发生直到被取消,而不是只发生一次。

我们将匿名函数传递setInterval,它将为我们完成我们的工作。第一行是:

currMarg = currMarg == 1800 ? 0 : currMarg + 600;

这是一个三元运算符它将分配currMarg的值0,如果currMarg等于1800,否则会增加currMarg600

对于第二行,我们只需将我们选择的值分配给containers marginLeft,我们就完成了!

注意:对于演示,我将负值更改为正值,因此效果是可见的。

点点!怎么说我们在最好的烟草管上庆祝我们的健康,我的好孩子?
2021-03-16 19:27:52
此外,随着 ES2015 对 JavaScript 的改进,现在可以在一行中编写一个简单的格式化函数:pastebin.com/b1n​​VqKZZ
2021-03-24 19:27:52
请看看这个并考虑进行修改。
2021-03-26 19:27:52
你知道,在实际阅读你的实现时,我注意到一些仍然需要解决的硬编码。请参阅此附录我可能最终会写出我自己的答案。
2021-04-03 19:27:52

Perhps 这就是你要找的。

var pos = 0;
window.onload = function start() {
    setTimeout(slide, 3000);
}
function slide() {
   pos -= 600;
   if (pos === -2400)
     pos = 0;
   document.getElementById('container').style.marginLeft= pos + "px";
   setTimeout(slide, 3000);
}
以这种方式使用 setTimeout 等同于使用 GOTO
2021-03-29 19:27:52

setTimeout()连续调用十次,因此它们几乎同时到期。你真正想要的是:

window.onload = function start() {
    slide(10);
}
function slide(repeats) {
    if (repeats > 0) {
        document.getElementById('container').style.marginLeft='-600px';
        document.getElementById('container').style.marginLeft='-1200px';
        document.getElementById('container').style.marginLeft='-1800px';
        document.getElementById('container').style.marginLeft='0px';
        window.setTimeout(
          function(){
            slide(repeats - 1)
          },
          3000
        );
    }
}

这将调用slide(10),然后设置3秒超时来调用slide(9),设置超时来调用slide(8),等等。当调用slide(0)时,不再有超时设置。

这违背了滑动照片展示的意义 - 在将容器移回原点之前,您不会将容器留在原处任何时间!
2021-03-14 19:27:52