我拥有的是一个数组:
var data = new Array();
data[0] = new Array();
data[0][0] = 'First_loc';
data[0][1] = '36.91781,36.63568';
data[1] = new Array();
data[1][0] = 'Second_loc';
data[1][1] = '36.88827,36.636908';
初始化Google地图后
var overlay;
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++) {
var name_1 = data[i][0];
var loc = data[i][1];
function HTMLMarker() {
this.pos = new google.maps.LatLng(loc);
}
HTMLMarker.prototype = new google.maps.OverlayView();
HTMLMarker.prototype.onRemove = function () {}
//init your html element here
HTMLMarker.prototype.onAdd = function () {
div = document.createElement('DIV');
div.className = "htmlMarker";
div.data = "data-price";
div.innerHTML = '<a href="#' + name_1 + '" class="pin_on_map"></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();
panes.overlayImage.style.left = position.x - 30 + 'px';
panes.overlayImage.style.top = position.y - 48 + 'px';
}
//to use it
var htmlMarker = new HTMLMarker(loc);
htmlMarker.setMap(gmap);
}
}
现在我正在循环这些函数(这并不好)我得到了最后一个值,所以我在地图上有两个具有相同值的引脚。 如果有人知道它的解决方案? 因此,在循环之后,我将使用具有不同值(位置和名称)的不同引脚
答案 0 :(得分:3)
您需要将标记创建代码移动到函数中,而不是将其放在for
循环体中。更改此代码:
for (var i = 0; i < data.length; i++) {
var name_1 = data[i][0];
var loc = data[i][1];
...
为:
for (var i = 0; i < data.length; i++) {
addMarker( data[i] );
}
function addMarker( place ) {
var name_1 = place[0];
var loc = place[1];
...
原始代码的问题在于,您的所有标记之间只共享name_1
和loc
变量的一个副本,并且当HTMLMarker
标记中的异步代码获得时在循环终止后调用long - 这些变量具有它们在最终循环迭代中具有的最后值。通过将代码移动到函数中,您可以获得每个循环迭代的闭包,因此每个标记都有这些变量的单独副本。
此更改还可以解决代码中的一个微妙问题:HTMLMarker
函数已在 for
循环内定义。这在JavaScript中并不是真的允许,但各种浏览器无论如何都会接受它 - 不同的浏览器会以不同的方式对待它。函数可以嵌套在其他函数中,但不能嵌套在循环或if
语句或类似的块中。
另外,我没有仔细查看HTMLMarker
实现,但在循环内(或现在在addMarker()
函数内)设置构造函数和原型并不理想。将它移到外面并将数据传递给构造函数会更好。你有LatLng
构造函数的问题 - 你传递的是一个字符串而不是两个数字。
你的标记DIV中没有任何实际文本,所以我更改了它以将名称放在标记内,并为它们添加了一些CSS样式,特别包括position:absolute
。
还有一点编码注释:某些HTMLMarker
方法中缺少分号。像这样的语句最后应该有一个分号:
HTMLMarker.prototype.onRemove = function () {};
最后,您设置标记像素位置的方式是错误的。代码设置了整个overlayLayer窗格的位置,而不是单个标记。我还改变了第一个标记的纬度,以便在它们之间留出一点空间。
修复所有这些,代码如下:
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 );
使用这个CSS:
.htmlMarker {
border: 1px solid #888;
background-color: white;
padding: 2px;
font-size: 14px;
position: absolute;
}
这是一个有效的fiddle。