使用setTimeOut在3秒后逐个显示标记..为什么它只显示最后一个标记?

时间:2013-06-07 07:39:00

标签: javascript jquery google-maps-api-3

我正在尝试使用setTimeOut逐个显示标记,但它无法正常工作。这是我的代码:

function showOneByOne(arrayOfMarkersObj) {
    for (u in arrayOfMarkersObj) {           
        setTimeout(function() {      
            arrayOfMarkersObj[u].setVisible(true);
        }, 3000);
    }
}

问题在于它只显示地图上的最后一个标记而不是所有标记。但是,如果我把

arrayOfMarkersObj[u].setVisible(true);

在setTimeOut之外,它显示所有标记。

为什么会这样?

2 个答案:

答案 0 :(得分:2)

将密钥存储到阵列中(如果您只使用支持ECMA5的浏览器,则可以按照Object.keys()的评论中的建议使用:

var keys = [];
for (u in arrayOfMarkersObj)
    keys.push(u); //assuming arrayOfMarkersObj is an object not an array?

现在逐一进入setTimeout

var current = 0;

function reveal() {
    arrayOfMarkersObj[keys[current++]].setVisible(true);
    if (current < keys.length) setTimeout(reveal, 3000);
}
reveal();

如果您希望第一个延迟切换最后一行:

setTimeout(reveal, 3000);

帖子中的示例不起作用的原因是因为u在调用时setTimeout不可用。事件setTimeout集调用的代码在window对象上调用。

为了使var可用,您需要将其存储为“升级”,通常是全局范围或包装函数内部(that = this作为参考this变为window然后使用that内的setTimeout来访问它。

答案 1 :(得分:1)

在JavaScript中,内部作用域中变量的值绑定到定义变量的作用域。这意味着回调在执行时将从定义u的范围中检索u的值,即showOneByOne()。因此,每次执行回调时,u将等于arrayOfMarkersObj.length -1for周期后的最终值)。

一种简单的解决方法应该是使用forEach,即使不清楚每个元素需要不同的回调/计时器。您也可以使用 Ken - Abdias Software 在答案中建议的单一内容。