Google地图HTMLMarker(循环不同的位置) [英] Google map HTMLMarker (loop different locations)

查看:80
本文介绍了Google地图HTMLMarker(循环不同的位置)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个数组:

  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; 

函数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 函数在中定义在 循环中。这在JavaScript中是不允许的,但各种浏览器都会接受它,不同的浏览器对它的处理方式也不同。函数可以嵌套在其他函数中,但不能嵌入循环中,或者 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 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.

这篇关于Google地图HTMLMarker(循环不同的位置)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆