2012-02-15 4 views
1

Я не понимаю, почему setTimeout работает не так, как я ожидал.setTimeout() и отбрасывающие маркеры на карте google

Я хочу бросить каждый маркер в другое время, а не все одновременно.

Paste и запустить этот код в http://jsfiddle.net, а затем удалить комментарии, чтобы увидеть смешное поведение:

 //setTimeout(function() { 
      addMarker(m); 
     //}, i * 500); 

.

<link href="http://code.google.com/apis/maps/documentation/javascript/examples/default.css" rel="stylesheet" type="text/css" /> 
<script type="text/javascript" src="//maps.googleapis.com/maps/api/js?sensor=false"></script> 
<script type="text/javascript"> 
    var berlin = new google.maps.LatLng(52.520816, 13.410186); 
    var neighborhoods = [ 
    new google.maps.LatLng(52.511467, 13.447179), 
    new google.maps.LatLng(52.549061, 13.422975), 
    new google.maps.LatLng(52.497622, 13.396110), 
    new google.maps.LatLng(52.517683, 13.394393) 
    ]; 
    var map; 
    function initialize() { 
    var mapOptions = { 
     zoom: 12, 
     mapTypeId: google.maps.MapTypeId.ROADMAP, 
     center: berlin 
    }; 
    map = new google.maps.Map(document.getElementById("map_canvas"),mapOptions); 
    } 

    function drop() { 
    var j = 0; 
    for (var i = 0; i < neighborhoods.length; i++) { 
     var m = neighborhoods[i]; 
     //setTimeout(function() { 
      addMarker(m); 
     //}, i * 500); 
    } 
    } 
    function addMarker(m) { 
    new google.maps.Marker({ 
     position: m, 
     map: map, 
     draggable: false, 
     animation: google.maps.Animation.DROP 
    }); 
    } 
</script> 
<body onload="initialize()"> 
<div id="map_canvas" style="width: 500px; height: 400px;">map div</div> 
<button id="drop" onclick="drop()">Drop Markers</button> 
</body> 
+0

Почему вы не вставляете код в jsfiddle и не отправляете ссылку на него? –

+0

jsfiddle - это серверы миграции, и в настоящее время никто не может сохранить код на нем – lito

ответ

7

Это потому, что значение «т» изменилось задолго до того, вызывает событие таймаута.

Вы должны обернуть этот код в закрытие, чтобы зафиксировать значение m.

Что-то вроде:

for (var i = 0; i < neighborhoods.length; i++) { 
    var m = neighborhoods[i]; 

    (function(n){ 
     setTimeout(function() { 
     addMarker(n); 
    }, i * 500); 
    }(m)); 
} 
2

Проблема ваша итерация над окрестностями и локальной переменной var m = neighborhoods[i]. Значение m, которое используется в addMarker(m), заменяется самым последним элементом в neighborhoods, что приведет к тому, что все маркеры будут выпадать на одном и том же месте.

Вместо этого используйте следующий код (JSFiddle). Он перебирает глобальный счетчик, который вы могли бы заменить статической переменной и устанавливает интервал вместо тайм-аут:

var droppedCount = 0; 
    var droppedInterval = null; 

    function drop() { 
    if(droppedCount === neighborhoods.length){ 
     clearInterval(droppedInterval); 
     return; 
    } 
    else if(droppedInterval === null) 
     droppedInterval = setInterval(drop,500); 

    var m = neighborhoods[droppedCount++]; 
    addMarker(m); 
    } 
+0

Да, я понимаю, что значение постоянно (4), но почему? как я могу это решить? – lito

+1

@lito: Я обновил свой ответ. Используйте глобальный или статический ('drop.droppedCount') счетчик. – Zeta

1

Проблема заключается в том, что функция в SetTimeout закрывает над переменной м, а не текущее значение его в момент создания. Решение должно быть:

// ... 
var m = neighborhoods[i]; 
(function (myMarker) { 
setTimeout(function() { 
    addMarker(myMarker); 
}, i * 500); 
}(m)); 
// ... 
Смежные вопросы