我有一个很长的for循环来在表中一次一行地验证文本框(超过1000行):我不断收到“停止运行此脚本”错误。很多网站都提到了setTimeout()函数。但我仍然无法让它发挥作用。这是我的代码:
var numRows = $("#tablex").attr('rows').length;
var errorMsg="";
for (var tbRow = 1; tbRow < numRows - 1; tbRow++) {
var aRecord = $("#tablex tr:eq(" + tbRow + ") td:eq(1)").attr("innerText");
var curECD = $("#tablex tr:eq(" + tbRow + ") td:eq(7)").find(':text').val().trim();
if (curECD != "" && isDate(curECD) == false)
errorMsg += "Date for " + aRecord + " is invalid<br/>";
}
任何人都可以帮忙吗?感谢!!!
答案 0 :(得分:0)
我做了这个this little example来帮助您使用setTimeout
枚举列表中的列表。
function enumerate(list, groupSize, callback, complete, debug){
var iterations = 0;
for (var i = 0; i < list.length; i+=groupSize, iterations++){
(function (group, index, isLast){ // new context
setTimeout(function(){
for (var j=0; j < group.length;j++){
debug && console.log(group[j]);
callback.call(group[j], (index+j+1));
}
isLast && complete.call();
}, 1);
})(list.slice(i, i+groupSize), i, (list.length < i+groupSize));
}
debug && console.log('iterations: ' + iterations);
}
这样称呼:
var trs = $('#tablex tr'),
errorMsg = '',
onItem = function(){
var aRecord = $("td:eq(1)", this).attr("innerText");
var curECD = $("td:eq(7)", this).find(':text').val().trim();
if (curECD != "" && isDate(curECD) == false)
errorMsg += "Date for " + aRecord + " is invalid<br/>";
},
complete = function(){
console.log(errorMsg);
};
enumerate(trs, 5, onItem, complete);
答案 1 :(得分:0)
我认为上面提到的第一个解决方案更好,但你也可以像我想的那样以递归的方式做到这一点。取决于您的要求:
var errorMsg="";
function validateRow(row, callback){
if(row.size() == 0){
callback();
}
var aRecord = $("td:eq(1)", row).attr("innerText");
var curECD = $("td:eq(7)", row).find(':text').val().trim();
if (curECD != "" && isDate(curECD) == false)
errorMsg += "Date for " + aRecord + " is invalid<br/>";
setTimeout(function(){
validateRow(row.next(), callback);
}, 25);
}
validateRow($("#tablex tr:first"), function(){
alert("finished validating");
});
这将调用validateRow并传入第一行。 ValidateRow将在setTimeout上调用自身并传入下一行。当它到达终点时,它将调用您提供的回调函数。