Google地图HTMLMarker(循环不同的位置) [英] Google map HTMLMarker (loop different locations)
问题描述
我有一个数组:
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;
循环中。这在JavaScript中是不允许的,但各种浏览器都会接受它,不同的浏览器对它的处理方式也不同。函数可以嵌套在其他函数中,但不能嵌入循环中,或者
函数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];
函数HTMLMarker(){
this.pos = new google.maps.LatLng(loc);
}
HTMLMarker.prototype = new google.maps.OverlayView();
HTMLMarker.prototype.onAddress = 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';
}
//使用它
var htmlMarker = new HTMLMarker(loc);
htmlMarker.setMap(gmap);
$ b现在我正在循环函数(它不是好)我得到最后一个值,所以我在地图上有两个具有相同值的引脚。
如果有人知道它的解决方案?
因此,循环后我将有不同的引脚与不同的值(位置和名称)
解决方案您需要移动标记创建代码放入一个函数中,而不是将它放在
的循环体内。更改此代码:
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]);
}
函数addMarker(place){
var name_1 = place [0];
var loc = place [1];
...
原始代码的问题是只有一个副本
name_1
和loc
变量在所有标记之间共享,并且当HTMLMarker
标记在循环终止后被称为—这些变量具有最后循环迭代中的最后一个值。通过将这些代码移动到一个函数中,每个循环迭代都会得到一个闭包,所以每个标记都有一个单独的副本。
这个变化也可以修复一个微妙的问题代码中的问题:
HTMLMarker
函数在中定义在if
语句或类似的块。另外,我并没有仔细观察HTMLMarker
实现,但在循环内建立构造函数和原型并不理想(或者现在在addMarker( )
函数)。将它移到外面并将数据传递给构造函数会更好。而你在LatLng
构造函数中有问题 - 你传递给它一个字符串而不是两个数字。
您的标记DIV中没有任何实际的文本,因此我将其更改为将标记放入标记中,并为它们添加了一些CSS样式,特别是
position:absolute
。
一些编码注释:在某些
HTMLMarker
方法中缺少分号。像这样的语句应该在最后有一个分号:
HTMLMarker.prototype.onRemove = function(){};
最后,您设置标记像素位置的方式是错误的。代码是设置整个叠加层窗格的位置,而不是单个标记。我也改变了第一个标记的纬度,给它们之间留出一点空间。
解决所有这些问题,代码如下所示:
var data = [
['First_loc','36 .95781,36.63568'],
['Second_loc','36 .88827,36.636908' ]
];
函数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';
};
函数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]);
}
函数addMarker(place){
var htmlMarker = new HTMLMarker(place);
htmlMarker.setMap(gmap);
}
}
google.maps.event.addDomListener(window,'load',initialize);
使用此CSS:
.htmlMarker {
border:1px solid#888;
背景颜色:白色;
padding:2px;
font-size:14px;
位置:绝对;
}
这里有一个工作小提琴。
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] = new Array(); data[1][0] = 'Second_loc'; data[1][1] = '36.88827,36.636908';
After I initialize Google Maps
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); } }
Now I am Looping the functions(and it is not good) And I get the last value so I have two pins on the map with the same values. If anybody know solution for it? So after looping I will have different pins with different values(Location and name)
解决方案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
andloc
variables shared among all your markers, and when the asynchronous code in yourHTMLMarker
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 thefor
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 orif
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 theaddMarker()
function). It would be better to move it outside and pass the data into the constructor. And you have a problem with theLatLng
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.
这篇关于Google地图HTMLMarker(循环不同的位置)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!