[英]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();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.