简体   繁体   English

将onclick侦听器添加到Google Maps Markers JavaScript

[英]Add onclick listener to Google Maps Markers JavaScript

I wrote this code: 我写了这段代码:

<script type="text/javascript">
    var address = JSON.parse('<?php echo $jsonLocations ?>');
    console.log(address.locations[0]);
    var latitude = '1';
    var longitude = '1';

    function initMap() {
        var map = new google.maps.Map(document.getElementById('map'), {
            zoom: 12,
            center: new google.maps.LatLng(latitude, longitude)
        });
        for(var i = 0; i < address.locations.length; i++){

            new google.maps.Marker({
                position: new google.maps.LatLng(address.locations[i]['lat'], address.locations[i]['long']),
                map: map
            }).addListener('click', function(){
                new google.maps.InfoWindow({
                    content: '<div id="content">'+
            '<div id="siteNotice">'+
            '</div>'+
            '<h5>' + i +'</h5>'+
            '<div id="bodyContent">'+
            '</div>'+
            '</div>'
                }).open(map, this);
            })
        }
    }

</script>

I'm trying to display i onClick of the marker. 我想,以显示i的onclick标记的。 So for the first maker I should be 0 and for the second 1. But somehow i is always the same value 所以对于第一大厂我应该是0和第二1.但不知何故, i始终是相同的值

This happens because the click event happens later in time and then i has the last value ... 发生这种情况是因为click事件发生的时间较晚,然后i有了最后一个值...

To fix this you can use a self invoking anonymous function inside the for loop - this way you will create a scope for each loop and the value of i will remain for the click when it happens. 要解决此问题,您可以在for循环内使用自调用匿名函数-这样,您将为每个循环创建一个作用域,并且click发生时, i的值将保持不变。

This is called Closure - you can read more about closures here and here 这称为闭包-您可以在此处此处阅读有关闭包的更多信息

 function initMap() { var address = { locations: [{ "lat": 30.53625, "lng": -111.92674, }, { "lat": 33.53625, "lng": -112.92674, }, { "lat": 32.53625, "lng": -111.92674, }, { "lat": 33.53625, "lng": -115.92674, }] }; var map = new google.maps.Map(document.getElementById('map'), { zoom: 4, center: new google.maps.LatLng(32.53625, -111.92674) }); var markers = []; for (var i = 0; i < address.locations.length; i++) { (function(index) { /* <--- Self invoking function */ var marker = new google.maps.Marker({ position: new google.maps.LatLng(address.locations[index]['lat'], address.locations[index]['lng']), map: map }); marker.addListener('click', function() { new google.maps.InfoWindow({ content: '<div id="content">' + '<div id="siteNotice">' + '</div>' + '<h5>' + index + '</h5>' + '<div id="bodyContent">' + '</div>' + '</div>' }).open(map, this); markers.push(marker); }); })(i); /* <---- Pass the index to the closure to keep its value */ } } 
 .as-console-wrapper{ display:none !important; } 
 <script async defer type="text/javascript" src="https://maps.google.com/maps/api/js?sensor=false&callback=initMap"></script> <div id="map" style="width:500px;height:150px"></div> 

This is a classic closure problem. 这是经典的关闭问题。 The function which is using the i variable is a async callback. 使用i变量的函数是异步回调。

The first thing what is happening is, that all the markers will be created. 发生的第一件事是,将创建所有标记。 Therefore i will be address.locations.length at the end of the loop. 因此, i将在循环结束时使用address.locations.length The async callbacks now reference this exact variable. 现在,异步回调会引用此确切变量。

There are some possible fixes for this: 有一些可能的修复程序:

use the let statement if you are able to use ES6 JavaScript features: 如果您能够使用ES6 JavaScript功能,请使用let语句:

for(let i = 0; i < address.locations.length; i++){
    [...]
}

The second one is to create a closure with this exact binding: 第二个方法是使用此确切的绑定创建一个闭包:

for(var i = 0; i < address.locations.length; i++){
    (function(i){
        [...]
    })(i)
}

The last option for you is to use the Function.bind method. 您的最后一个选择是使用Function.bind方法。

for(var i = 0; i < address.locations.length; i++){

    new google.maps.Marker({
        position: new google.maps.LatLng(address.locations[i]['lat'], address.locations[i]['long']),
        map: map
    }).addListener('click', (function(i){
        new google.maps.InfoWindow({
            content: '<div id="content">'+
    '<div id="siteNotice">'+
    '</div>'+
    '<h5>' + i +'</h5>'+
    '<div id="bodyContent">'+
    '</div>'+
    '</div>'
        }).open(map, this);
    }).bind(this,i))
}

I hope that one of this methods will work for you. 我希望其中一种方法对您有用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM