What I have is a an array:
var data = new Array();
data[0] = new Array();
data[0][0] = \'First_loc\';
data[0][1] = \'36.91781,36.63568\';
data[1]
You need to move your marker creation code into a function instead of having it in the body of the for
loop. Change this code:
for (var i = 0; i < data.length; i++) {
var name_1 = data[i][0];
var loc = data[i][1];
...
to:
for (var i = 0; i < data.length; i++) {
addMarker( data[i] );
}
function addMarker( place ) {
var name_1 = place[0];
var loc = place[1];
...
The problem with the original code is that there's only a single copy of the name_1
and loc
variables shared among all your markers, and when the asynchronous code in your HTMLMarker
markers gets called—long after the loop terminates—these variables have the last values they had in the final loop iteration. By moving that code into a function, you get a closure for each loop iteration so each marker has a separate copy of those variables.
This change also happens to fix a subtle problem in the code: the HTMLMarker
function was defined inside the for
loop. This is not really allowed in JavaScript, but the various browsers accept it anyway—and different browsers treat it differently. Functions may be nested inside other functions, but not inside loops or if
statements or similar blocks.
Also, I didn't look closely at the HTMLMarker
implementation, but it's not ideal to set up that constructor and prototype inside the loop (or now inside the addMarker()
function). It would be better to move it outside and pass the data into the constructor. And you have a problem with the LatLng
constructor - you're passing it a string instead of two numbers.
Your marker DIVs didn't have any actual text in them, so I changed it to put the name inside the tag, and added some CSS styling for them, including in particular position:absolute
.
A little coding note too: there were semicolons missing on some of the HTMLMarker
methods. A statement like this should have a semicolon at the end:
HTMLMarker.prototype.onRemove = function () {};
And finally, the way you were setting the marker's pixel position is wrong. The code was setting the position of the entire overlayLayer pane, not the individual marker. I also changed the latitude of the first marker to give a little room between them.
Fixing all of these, the code looks like:
var data = [
[ 'First_loc', '36.95781,36.63568' ],
[ 'Second_loc', '36.88827,36.636908' ]
];
function HTMLMarker( place ) {
var latLngStrings = place[1].split(',');
var lat = +latLngStrings[0];
var lng = +latLngStrings[1];
this.name = place[0];
this.pos = new google.maps.LatLng( lat, lng );
}
HTMLMarker.prototype = new google.maps.OverlayView();
HTMLMarker.prototype.onRemove = function () {};
HTMLMarker.prototype.onAdd = function () {
var div = this.div = document.createElement('DIV');
div.className = "htmlMarker";
div.data = "data-price";
div.innerHTML = '<a href="#' + this.name + '" class="pin_on_map">' + this.name + '</a>';
var panes = this.getPanes();
panes.overlayImage.appendChild(div);
};
HTMLMarker.prototype.draw = function () {
var overlayProjection = this.getProjection();
var position = overlayProjection.fromLatLngToDivPixel(this.pos);
var panes = this.getPanes();
this.div.style.left = position.x - 30 + 'px';
this.div.style.top = position.y - 48 + 'px';
};
function initialize() {
var myLatLng = new google.maps.LatLng(36.88827, 36.636908);
var mapOptions = {
zoom: 9,
center: myLatLng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var gmap = new google.maps.Map(document.getElementById('map_canvas'), mapOptions);
for (var i = 0; i < data.length; i++) {
addMarker( data[i] );
}
function addMarker( place ) {
var htmlMarker = new HTMLMarker( place );
htmlMarker.setMap(gmap);
}
}
google.maps.event.addDomListener( window, 'load', initialize );
with this CSS:
.htmlMarker {
border: 1px solid #888;
background-color: white;
padding: 2px;
font-size: 14px;
position: absolute;
}
And here's a working fiddle.