Javascript函数工作一段时间,然后冻结浏览器

Javascript函数工作一段时间,然后冻结浏览器,javascript,Javascript,我正在使用此JS代码制作横幅: var images = ["../../images/g11.jpg","../../images/g9.jpg","../../images/g10.jpg"]; var titulos = ["title1","title2","title3"]; var resumos = ["ddd","aaa","bbb"]; var noticias = ["190","204","200"]; var total = 3; var indice = 0; fu

我正在使用此JS代码制作横幅:

var images = ["../../images/g11.jpg","../../images/g9.jpg","../../images/g10.jpg"];
var titulos = ["title1","title2","title3"];
var resumos = ["ddd","aaa","bbb"];
var noticias = ["190","204","200"];

var total = 3;
var indice = 0;

function rotate() {
    document.getElementById('imageb').src = images[indice];
    document.getElementById('titulob').innerHTML = titulos[indice];
    document.getElementById('resumob').innerHTML = resumos[indice];
    document.getElementById('noticiab').value = noticias[indice];
    indice++;
    if (indice > total - 1) indice = 0;
}

function banner() {
    rotate();
    setTimeout(banner, 5000);
}
它按预期的方式工作,但经过一些循环后,它会冻结浏览器。我很确定我没有正确使用setTimeout。有什么想法吗

编辑:

迄今为止的工作:

function rotate(indice) {
    document.getElementById('imageb').src = images[indice];
    document.getElementById('titulob').innerHTML = titulos[indice];
    document.getElementById('resumob').innerHTML = resumos[indice];
    document.getElementById('noticiab').value = noticias[indice];
}

function banner(indice) {
    var f1 = function() { banner(indice); };
    var total = 3;
    rotate(indice);
    indice++;
    if (indice > total - 1) indice = 0;
    setTimeout(f1, 5000);
}

我把这个贴成CW,因为这完全是猜测

完全是FWIW,下面是我如何最小限度地修改代码的:|

变化:

  • 将所有内容放在作用域函数中,以避免创建全局变量

  • 使用对象数组而不是并行数组

  • 使用数组的长度,而不是单独的
    total
    变量

  • 使用余数技巧获得
    indice
    变量的换行符

  • 我添加了对
    banner()的调用在最后开始,但我假设你有,只是没有显示它


  • 但是,我也不认为你的代码不应该按原样工作,除了可能出现一些奇怪的全局变量冲突之外。

    我认为这是一种更好的方式,可以让其他人清楚地看到他的代码,它被作为一个函数调用,我没说这能解决他的问题problem@nrathaus:很明显,
    banner
    是作为函数调用的。这也很好,因为
    banner
    是一个函数,除了函数,您不能调用任何东西!:-)@T.J.Crowder“你只能调用函数”——出于某种原因,我现在想找到一些模糊的技术细节来证明这一点是错误的;)@迈克·波马克斯·卡曼斯:我从来没有说过
    setTimeout
    只能执行函数。我说你只能调用函数。非常正确的是,如果不是因为上面两行的定义,
    banner
    符号很可能被解析为一个包含字符串的变量。我想这就是nrathaus的意思。@Jairo:如果你无法捕捉到它冻结了,而这里聚集的人群也看不出为什么会冻结,我会把它归结为“这些事情之一”。(我上面的原始代码的jsbin仍然在愉快地运行着…)我会使用setInterval over setTimeout来确保你在任何给定时间都不会旋转超过一次。虽然这看起来不像是超时5000的问题,但它确实澄清了代码的行为,并保证不会出现此问题。它还使停止和启动旋转动画变得更加简单。@Deadron:但上述操作不会导致重叠旋转,因此不需要使用
    setInterval
    来确保这一点。很明显,在上一次运行完成之前,我们不会安排下一次运行。我不太喜欢
    setInterval
    。一些浏览器测量从调用回调开始的时间间隔,其他浏览器测量从回调返回开始的时间间隔。我更喜欢链式
    setTimeout
    。当然,这是一个选项。“一些浏览器测量从调用回调开始的时间间隔,其他浏览器测量从回调返回开始的时间间隔。我更喜欢链式setTimeout”-等等什么?他建议一些浏览器等到函数完成后才开始下一次调用的延时,而其他浏览器则会在每次达到间隔时启动函数。由于非特定语言,在实际规范中似乎没有定义。我的理解是,至少在当前正在执行时,它不应该试图调用函数。@BenjaminGruenbaum:这是真的,或者至少是我最后一次检查时(我承认这可能是四年多以前的事了——我们知道从那时起事情有了多大的改进)。假设您执行
    setInterval(foo,1000)
    并且
    foo
    运行需要250毫秒(夸张的示例)。一些浏览器在上次启动对
    foo
    的调用后1000毫秒会调用
    foo
    ,因此
    foo
    每隔1000毫秒运行一次。其他人则更像上面那样安排它,当
    foo
    返回时,因此它每1250ms运行一次。但大多数情况下,我只是喜欢控制说“除非我重新安排,否则它不会再运行。”
    (function() {
        var entries = [
            {
                img:        "../../images/g11.jpg",
                titulo:     "title1",
                resumo:     "ddd",
                noticia:    "190"
            },
            {
                img:        "../../images/g9.jpg",
                titulo:     "title2",
                resumo:     "aaa",
                noticia:    "204"
            },
            {
                img:        "../../images/g10.jpg",
                titulo:     "title3",
                resumo:     "bbb",
                noticia:    "200"
            }
        ];
    
        var indice = 0;
    
        function rotate() {
            var entry = entries[indice];
            document.getElementById('imageb').src = entry.img;
            document.getElementById('titulob').innerHTML = entry.titulo;
            document.getElementById('resumob').innerHTML = entry.resumo;
            document.getElementById('noticiab').value = entry.noticia;
    
            indice = (indice + 1) % data.length;
        }
    
        function banner() {
            rotate();
            setTimeout(banner, 5000);
        }
    
        banner();
    })();