我正在一个需要在表格中在线滚动用户列表的项目。这个想法是服务器被ping到整个列表,它填充前5个然后删除顶部并在2.5秒间隔添加下一个。整个列表完成后,我需要点击服务器获取最新列表并永远重复。
我遇到的问题是“永远”的问题。虽然第一次加载很好并且循环工作很好,但第二次加载有问题。如果// get_users_online_today();取消注释,看起来好像在第一个setTimeout()触发器完成后调用发生。
我似乎无法弄清楚将函数放在函数内的位置,以便重复调用它。
$(function(){
function get_users_online_today(){
var user = 0;
$.ajax({
url: 'ajax.php',
data: {action: 'Users Online Today'},
dataType: 'json'
}).done(function(users){
$.each(users, function(index, details){
if($('#users_online_today tbody tr').length <= 5){
$('#users_online_today tbody').append('<tr><td>' + details.name + '</td></tr>');
}else{
setTimeout(function(){
$('#users_online_today tbody tr:first').remove();
$('#users_online_today tbody').append($('<tr><td>' + details.name + '</td></tr>').fadeIn(250));
}, (user++) * 2500);
}
});
//get_users_online_today();
});
}
get_users_online_today();
});
答案 0 :(得分:0)
在setTimeout周围添加一个闭包,以便它正确引用你在循环中的用户应该可以解决你的问题。现在代码中发生的事情是,当setTimeout实际发生时,它会查看先前作用域的“用户”(最后一个用户),而不是包含正确值的本地范围变量。
(function(i, d){
setTimeout(function(){
$('#users_online_today tbody tr:first').remove();
$('#users_online_today tbody').append($('<tr><td>' + d.name + '</td></tr>').fadeIn(250));
}, (i + 1) * 2500);
}(index, details));
您也不需要该用户变量,因为您在.each()函数中传递了用户的索引。除非你出于其他原因使用它,否则只需在超时功能之前/之后将其设置为+ = 1。
这里有一个更好的解释,关闭是什么以及它们有用的原因: How do JavaScript closures work?