1

我试图以 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 。

4

7 回答 7

4

最干净的解决方案就是让你的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功能

于 2012-11-10T15:16:57.403 回答
2
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/


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

于 2012-11-10T15:13:53.263 回答
2

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

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

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

于 2012-11-10T14:58:52.030 回答
2

的范围存在问题ì,延迟需要相应地增加以具有 200 毫秒的间隔,以及期望函数作为参数i的事实。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
    };
于 2012-11-10T14:59:56.890 回答
2

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

    var callback = function(i) {
        return function() {
            if (i < elms.length) {
                clickLink(inputs[i]);
                setTimeout(callback(i + 1), 200);
            }
        };
    };
    setTimeout(callback(250), 200);
于 2012-11-10T15:30:20.893 回答
1

你这样做的方式不会让你每 200 毫秒点击一次,你将几乎同时注册所有点击(循环最后一次迭代 1000 个项目的时间,几乎是立即)所以你基本上会得到你的 1000+ aprox。单击事件几乎同时触发,我认为这可能会导致问题,因此要确保它们在大约 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以避免注释中提到的关闭问题。

更新 2window.i在匿名函数中添加了解决i范围问题

更新 3:更新了我上面的代码以修复触发每个点击事件的时间间隔,我们正在使用200 * i但只有i从零开始才是正确的,这里它从 250 开始,所以正确的形式是200 * (i-249)

尽管有一些评论,但i它已解决的范围问题window.i,请参阅此处的测试https://tinker.io/98fd4/1

于 2012-11-10T14:54:26.717 回答
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/

于 2012-11-10T15:29:46.097 回答