Google maps - multiple markers with unique infowindows

半腔热情 提交于 2021-01-28 08:02:54

问题


I am creating a map for users on my website. The way it works is I use PHP and AJAX to get all the sites users addresses, I then pass these values to my JS as JSON where I generate a google map centered around the current users address with a marker for each user on the map. This part works at the moment but what I'm struggling with is generating a unique infowindow for each user. As it is right now I get the same info window for all markers, how can I fix this?

JS

jQuery(document).ready(function($){
    $.ajax({
        url: ajax_url,
        type: 'post',
        dataType: 'json',
        data: { 
            action: 'map' 
        },
        error : function(response){
            console.log(response);
        },
        success : function(response){
            var mapOptions = {
                zoom: 16,
            }

            var geocoder = new google.maps.Geocoder();
            var infowindow = new google.maps.InfoWindow();

            // current user position
            geocoder.geocode({'address': response.current[0].postcode}, function(results, status){
                map.setCenter( results[0].geometry.location );

                var marker = new google.maps.Marker({
                    map: map,
                    position: results[0].geometry.location
                });
            });

            // other users loop
            for( var i = 0; i < response.other.length; i++ ){
                var postcode = response.other[i].postcode;

                geocoder.geocode( {'address': postcode}, function(results, status){
                    var marker = new google.maps.Marker({
                        map: map,
                        position: results[0].geometry.location
                    });

                    google.maps.event.addListener(marker, 'click', function(){
                        infowindow.close(); // Close previously opened infowindow
                        infowindow.setContent( "<div id='infowindow'>"+ postcode +"</div>");
                        infowindow.open(map, this);
                    });
                });
            }

            var map = new google.maps.Map(document.getElementById("buddy_map"), mapOptions);

            return false;
        }
    });
});

PHP

add_action('wp_ajax_nopriv_map', 'addresses');
add_action('wp_ajax_map', 'addresses');


function addresses(){
    global $current_user;

    $address_street = get_user_meta( $current_user->ID, 'shipping_address_1', true );
    $address_city = get_user_meta( $current_user->ID, 'shipping_city', true );
    $address_postcode = get_user_meta( $current_user->ID, 'shipping_postcode', true );
    $address = $address_street . ', ' . $address_city . ', ' . $address_postcode;

    $cur_user[] = array(
        "postcode" => $address
    );

    $other_users[] = array(
        "postcode" => "LS11 6NA"
    );

    $other_users[] = array(
        "postcode" => "LS11 6LY"
    );

    echo json_encode( array( "current" => $cur_user, "other" => $other_users) );

    die();
}

I know my PHP file needs some work its just a rough draft to get this working first.


回答1:


You need to use a closure in your for loop.

You can read Google documentation on Using closures in event listeners.

See the basic example below and note the use of the closure in the marker click event listener.

function initialize() {

    var mapOptions = {
        zoom: 5,
        mapTypeId: google.maps.MapTypeId.ROADMAP,
        center: new google.maps.LatLng(1, 1)
    };

    var locations = [
        [new google.maps.LatLng(0, 0), 'Marker 1', 'Infowindow content for Marker 1'],
        [new google.maps.LatLng(0, 1), 'Marker 2', 'Infowindow content for Marker 2'],
        [new google.maps.LatLng(0, 2), 'Marker 3', 'Infowindow content for Marker 3'],
        [new google.maps.LatLng(1, 0), 'Marker 4', 'Infowindow content for Marker 4'],
        [new google.maps.LatLng(1, 1), 'Marker 5', 'Infowindow content for Marker 5'],
        [new google.maps.LatLng(1, 2), 'Marker 6', 'Infowindow content for Marker 6']
    ];

    var map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);

    var infowindow = new google.maps.InfoWindow();

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

        var marker = new google.maps.Marker({
            position: locations[i][0],
            map: map,
            title: locations[i][1]
        });

        google.maps.event.addListener(marker, 'click', (function (marker, i) {

            return function () {
                infowindow.setContent(locations[i][2]);
                infowindow.open(map, marker);
            }

        })(marker, i));
    }
}
#map-canvas {
  height: 160px;
}
<div id="map-canvas"></div>

<!-- Replace the value of the key parameter with your own API key. -->
<script async defer src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initialize">
</script>

To illustrate with the use of the Geocoder, please see the below snippet. As I said in a comment, the Geocoder service has a QPS limit of 50 requests per second. If your locations list has more than 50 items, it is very likely that it will fail as the loop will be executed in less than 1 second.

function initialize() {

  var geocoder = new google.maps.Geocoder();
  var mapOptions = {
    zoom: 12,
    mapTypeId: google.maps.MapTypeId.ROADMAP,
    center: new google.maps.LatLng(40.718193, -74.001339)
  };

  var locations = [
    ['Marker 1', 'Infowindow content for Marker 1', '10001, USA'],
    ['Marker 2', 'Infowindow content for Marker 2', '10002, USA'],
    ['Marker 3', 'Infowindow content for Marker 3', '10003, USA'],
    ['Marker 4', 'Infowindow content for Marker 4', '10004, USA'],
    ['Marker 5', 'Infowindow content for Marker 5', '10005, USA'],
    ['Marker 6', 'Infowindow content for Marker 6', '10006, USA']
  ];

  var map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
  var infowindow = new google.maps.InfoWindow();

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

    geocoder.geocode({
      'address': locations[i][2]
    }, (function(locations, i) {

      return function(results, status) {

        var marker = new google.maps.Marker({
          map: map,
          position: results[0].geometry.location,
          title: locations[i][0]
        });

        google.maps.event.addListener(marker, 'click', (function(marker) {

          return function() {

            infowindow.setContent("<div id='infowindow-content'><h3>" + locations[i][1] + "</h3>" + results[0]['formatted_address'] + "</div>");
            infowindow.open(map, marker);
          }

        })(marker));
      }
    })(locations, i));
  }
}
#map-canvas {
  height: 160px;
}
<div id="map-canvas"></div>

<!-- Replace the value of the key parameter with your own API key. -->
<script async defer src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initialize">
</script>


来源:https://stackoverflow.com/questions/56869829/google-maps-multiple-markers-with-unique-infowindows

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!