views:

1184

answers:

4

I'm working on a page which fetches code with a Javascript httpObject and uses it to update two elements on the page - a google map, and a DIV that lists the things the marker points to.

That bit works fine. The problem is that when I create the markers, I do so through a for loop, and I add listeners to the marker in each loop. Then, when I test the page, I find the same thing happens for every marker.

Hovering over a marker should change the border colour of the corresponding bit of the DIV. Instead, each marker changes the border of the last bit. It seems like each time I add the listeners I overwrite the listeners of the previously added markers too.

I get that this is to do with the Google Maps API retaining the identity of a marker even when you create a new one in Javascript. What I don't get it how to get around it - I tried creating an array outside the loop, and changing

var newMarker = new GMarker(newLatLng);

with newMarker[count] = new GMarker(newLatLng);

but it still doesn't work.

Help Me, StackOverflow. You're my only hope. :)

Edit: A little more code

for (count=0;count<=LatArray.length;count++)
{
  thisLat = LatArray[count];
  thisLong = LongArray[count];
  thisHTML = HTMLArray[count];
  newLatLng = new GLatLng(thisLat, thisLong, true);

  if (mapBounds.containsLatLng(newLatLng))
  {
      //alert(count);
      var  dinnerNumber = "dinner_"+count;
      newMarkers[count] = new GMarker(newLatLng); 
      map.addOverlay(newMarkers[count]);
      GEvent.addListener(newMarkers[count],'mouseover',function(){document.getElementById(dinnerNumber).style.borderColor = '#000000';
  });
}// for
+2  A: 

Closure issue -- all those listeners share the same dinnerNumber variable. Try this:

GEvent.addListener(newMarkers[count], 'mouseover', (function(dinnerNumber){ return function(){document.getElementById(dinnerNumber).style.borderColor = '#000000';}; })(dinnerNumber));

This way, each listener is created with its own closed copy of dinnerNumber.

Justin Ludwig
Thanks Justin!I haven't a clue whats going on at the end there, but it works. I'll pull it apart and see if I can make sense of it, but for now you've solved my problem!
Alan Jack
Check out http://robertnyman.com/2008/10/09/explaining-javascript-scope-and-closures/ for a really good explanation of closures and the "infamous loop problem."
Justin Ludwig
A: 
George Morris
+1  A: 

You have to read carefully

GEvent.addListener(newMarkers[count], 'mouseover', 
       (function(dinnerNumber)
          { return function()
                { document.getElementById(dinnerNumber).style.borderColor = '#000000';};        
          }
      )(dinnerNumber)
);

you missed one ();

the 3-rd parameter is (function(var){return function(){//what you want wirh var;};})(var)

ovi
A: 

Excellent answer - dont think i would have ever figured this out!

Andy