繁体   English   中英

JavaScript循环问题

[英]Javascript For-Loop issue

我试图以200毫秒的间隔单击每个项目,我编写了以下脚本,但是For循环似乎存在问题。 请有人告诉我您认为这有什么问题。

function clickLink(elm) {
    var evt = document.createEvent('MouseEvents');
    evt.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
    elm.dispatchEvent(evt);
}

function sel() {
    elms = document.getElementsByClassName('uItem');
    var inputs= elms;
    var howbig= elms.length;
    console.log(howbig);

    for (var i=250;i<elms.length;i++)
    {
        setTimeout(clickLink(inputs[i]),200)
    };

页面上有1400个uItem。

最干净的解决方案就是让您的clickLink函数返回一个函数。

function clickLink(elm) {
    return function() {
        var evt = document.createEvent('MouseEvents');
        evt.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
        elm.dispatchEvent(evt);
    };
}

然后,如果需要间隔,请错开计时器:

var start = 250
for (var i=start;i<elms.length;i++) {
    setTimeout(clickLink(elms[i]), 200 * (i - start))
}

或者放弃循环,并使用setInterval

var i = 250,
    len = inputs.length;
var itvl = setInterval(function() {
    clickLink(elms[i++]);
    if (i >= len)
        clearInterval(itvl);
}, 200);

并返回到原始的clickLink函数

如果您使用的是中等版本的JavaScript,最简单的方法是使用bind 这将创建一个具有绑定到其的参数的单个函数对象,该参数是在调用bind时计算的,而不是稍后进行计算。 因此,您想要的行是:

setTimeout( clickLink.bind( null, inputs[i] ),  /* delay expression here */ )

您可以显式地创建绑定函数,但这很丑陋,只有在您强烈要求支持旧的JavaScript解释器时才应该这样做。

存在ì范围的问题,该延迟需要随着i以200 ms的间隔相应地增加,并且setTimeout期望函数作为参数。

    for (var i=250;i<elms.length;i++)
    {
        setTimeout((function() {
            var j = i // keep i as j in this closure
            return function() { // return the right function
                clickLink(inputs[j])
            }
        })(),200 * i) // set the delay depending on i
    };
function sel() {
  var elems = document.getElementsByClassName('uItem');
  for (var i = 0; i < elems.length; i += 1) {
    setTimeout(function (el) {
      return function () {
        clickLink(el);
      };
    }(elems[i]), i * 1000);   
  };
}

演示: http : //jsfiddle.net/4hYWy/


小提示 :我不喜欢这些构造(像示例中那样计算延迟)。 但这与原始代码非常接近,我选择的解决方案可能会使它过于复杂。

此代码等待200毫秒,执行回调并准备在200毫秒后执行的新回调。 第二个回调是在sel调用之后400毫秒执行的,依此类推。

    var callback = function(i) {
        return function() {
            if (i < elms.length) {
                clickLink(inputs[i]);
                setTimeout(callback(i + 1), 200);
            }
        };
    };
    setTimeout(callback(250), 200);

这样一来,您不会每200毫秒获得一次点击,您几乎可以同时注册所有点击(一次循环几乎可以立即迭代1000个项目的时间),因此您基本上可以获得1000+个近似值。 点击事件几乎同时触发,我认为这可能会引起问题,因此请确保它们在大约200毫秒内执行一次。 做这个:

window.i=250;
for (var i=250;i<elms.length;i++)
{
setTimeout(function() {
   clickLink(inputs[window.i]);
   window.i++;
},200 * (i-249)); //Here we make sure events are spaciated 200ms each approx.
};

更新: 更新了匿名函数以传递 i以避免注释中指出的关闭问题。

更新2 :在匿名函数中添加了window.i以解决i作用域问题

更新3 :更新了上面的代码,以固定每次单击事件触发的时间间隔,我们使用200 * i但这仅在i从零开始时正确,此处从250开始,因此正确的格式为200 * (i-249)

尽管有一些评论,但使用window.i解决了i范围问题,请参见此处进行测试https://tinker.io/98fd4/1

没有范围问题或计算正确的间隔。

function sel() {
    var elms = document.getElementsByClassName('uItem'),
        i = -1,
        I = elms.length,

        rec = function () {
            if ( i++ < I ) {
                clickLinks(elms[i]);
                setTimeout(rec, 200);
            }
        };

    rec();
}

http://jsfiddle.net/joplomacedo/cqfxH/

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM