javascript - Google map HTMLMarker(循环不同位置)

标签 javascript jquery google-maps

我有一个数组:

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 map 后

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);
    }
}

现在我正在循环函数(这不好)并且我得到了最后一个值,所以我在 map 上有两个具有相同值的图钉。 如果有人知道解决方案吗? 因此,循环后我将拥有具有不同值(位置和名称)的不同引脚

最佳答案

您需要将标记创建代码移至函数中,而不是将其放在 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_1loc 变量只有一个副本,并且当您的 HTMLMarker 标记在循环终止后很长时间内被调用,这些变量具有它们在最终循环迭代中的最后值。通过将该代码移动到函数中,您可以为每个循环迭代获得一个闭包,因此每个标记都有这些变量的单独副本。

此更改还修复了代码中的一个微妙问题:HTMLMarker 函数是在 for 循环内定义的。这在 JavaScript 中实际上是不允许的,但各种浏览器无论如何都接受它——并且不同的浏览器以不同的方式对待它。函数可以嵌套在其他函数内,但不能嵌套在循环或 if 语句或类似 block 内。

此外,我没有仔细研究 HTMLMarker 实现,但在循环内(或现在在 addMarker() 内)设置该构造函数和原型(prototype)并不理想代码 > 函数)。最好将其移到外部并将数据传递到构造函数中。而且 LatLng 构造函数存在问题 - 您向它传递的是一个字符串而不是两个数字。

您的标记 DIV 中没有任何实际文本,因此我将其更改为将名称放入标记内,并为其添加了一些 CSS 样式,特别包括 position:absolute

还有一点编码注释:某些 HTMLMarker 方法中缺少分号。像这样的语句末尾应该有一个分号:

HTMLMarker.prototype.onRemove = function () {};

最后,您设置标记像素位置的方式是错误的。该代码设置整个overlayLayer Pane 的位置,而不是单个标记。我还更改了第一个标记的纬度,以便在它们之间留出一点空间。

解决所有这些问题,代码如下所示:

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 .

关于javascript - Google map HTMLMarker(循环不同位置),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17131419/

相关文章:

javascript - Jquery 只影响被悬停的类中的一个元素

javascript - Meteor JS - 添加新帖子时 $sort 不起作用

javascript - 将 [object Object] 转换为 DOM 元素

javascript - 使用 php 调用 javascript 函数

android - 在运行时设置 Google Maps v2 API key

android - TextView 未显示在 Google map 的顶部

google-maps - 如何防止 Google Maps API v3 DirectionsService 生成的结果受到当前交通状况的影响?

javascript - 具有不同模式的对象数组 - JOI

javascript - 无法使用 form2js.js 将表单数据转换为 JSON 对象

jQuery UI Datepicker - 前端动态日期格式但后端静态日期格式?