Reputation: 10447
I'm working with the Google Map API v3 to try and populate a map with people advertising their availability for work. The map outputs fine and populates fine and I'm using the animate drop in feature to make them fall in nicely. However they all fall in one go and I want to make them fall one at a time, adding a simple delay is the solution and Google itself has that as an example. The only difference is I have an array full of results.
locations = [
<?php foreach($searchResults as $clID => $r) { ?>
['<?php echo $r['clUserName']; ?>', <?php echo $r['clLat']; ?>, <?php echo $r['clLng']; ?>, '<?php echo '<div style="width: 100%"><div style="font-weight: bold; line-height: 25px;">' . $r['clUserName'] . '</div>Distance: ' . number_format($r['distance'], 0) . ' miles<br />Will Travel: ' . $r['clWorkRadius'] . ' miles<br />E-mail: <a style="color: #222 !important;;" href="mailto:' . $r['clEmail'] . '"><u>' . $r['clEmail'] . '</u></a><br />Tel: ' . $r['clTelephone'] . ($r['clMobile'] ? '<br />Mob: ' . $r['clMobile'] : '') . '</div>'; ?>'],
<?php } ?>
];
function initialize() {
var mapOptions = {
zoom: 10,
center: new google.maps.LatLng(<?php if($_SESSION['search']['geo']['lat'] !== 0) { echo $_SESSION['search']['geo']['lat'] . ',' .$_SESSION['search']['geo']['lng']; } else { echo '51.507335,-0.127683'; } ?>),
mapTypeId: google.maps.MapTypeId.ROADMAP
}
var map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
var infowindow = new google.maps.InfoWindow();
var marker;
for(i = 0; i < locations.length; i++) {
marker = new google.maps.Marker({
position: new google.maps.LatLng(locations[i][1], locations[i][2]),
animation: google.maps.Animation.DROP,
map: map
});
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infowindow.setContent(locations[i][3]);
infowindow.open(map, marker);
}
})(marker, i));
}
}
function loadScript() {
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "http://maps.googleapis.com/maps/api/js?key=AIzaSyA6Bru5lLQukzGx3f-AVOBTPmxglkqI5m4&sensor=false&callback=initialize";
document.body.appendChild(script);
}
window.onload = loadScript;
To stagger the dropping of people on the map I added a setTimeout around the marker, delaying each one slightly longer. However doing so breaks the code. I keep getting a javascript error TypeError: locations[i] is undefined. Why would simply wrapping the code in a setTimeout stop it from being able to see locations?
var marker;
for(i = 0; i < locations.length; i++) {
setTimeout(function() {
marker = new google.maps.Marker({
position: new google.maps.LatLng(locations[i][1], locations[i][2]),
animation: google.maps.Animation.DROP,
map: map
});
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infowindow.setContent(locations[i][3]);
infowindow.open(map, marker);
}
})(marker, i));
}, 500);
}
Upvotes: 0
Views: 532
Reputation: 4257
You didn't wrap the callback you are passing to setTimeout
in a self-evaluating function with the i
variable, so by the time the callback was called, i === locations.length
(the terminating case of the loop).
var marker;
for (i = 0; i < locations.length; i++) {
setTimeout((function (i) {
return function () {
marker = new google.maps.Marker({
position: new google.maps.LatLng(locations[i][1], locations[i][2]),
animation: google.maps.Animation.DROP,
map: map
});
google.maps.event.addListener(marker, 'click', (function (marker, i) {
return function () {
infowindow.setContent(locations[i][3]);
infowindow.open(map, marker);
}
})(marker, i));
};
})(i), 500);
}
Upvotes: 1