简体   繁体   English

将相同的onClick事件附加到Google Map标记

[英]Attaching the same onClick event to Google Map markers

The code below is from a Google Maps tutorial, with some changes for something I'm working on (so some parts won't make sense right now). 以下代码来自Google Maps教程,并对我正在处理的内容进行了一些更改(因此,某些部分目前尚无意义)。

It has an onClick event for the map, so if you click a random place on the map, or if you click a specific "place" it will show directions. 它具有地图的onClick事件,因此,如果您单击地图上的随机位置,或者单击特定的“位置”,它将显示方向。

However, I want to attach the same onClick event to the markers. 但是,我想将相同的onClick事件附加到标记。 This code uses "prototype" which I'm not overly familiar with. 这段代码使用的是我不太熟悉的“原型”。

Really, at this point, all I need to know is how to call the ClickEventHandler function when a marker is clicked. 确实,在这一点上,我所需要知道的是单击标记时如何调用ClickEventHandler函数。 The function is called properly for "place" clicks, and random map clicks, but not for clicks on map markers. 对于“放置”点击和随机地图点击,将正确调用该函数,但对于地图标记的点击则不会正确调用该函数。

Thanks in advance for any insight you can provide. 在此先感谢您提供的任何见解。

<!DOCTYPE html >
  <head>
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
    <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
    <title>Using MySQL and PHP with Google Maps</title>
    <style>
      /* Always set the map height explicitly to define the size of the div
       * element that contains the map. */
      #map {
        height: 100%;
      }
      /* Optional: Makes the sample page fill the window. */
      html, body {
        height: 100%;
        margin: 0;
        padding: 0;
      }
    </style>
  </head>

  <body>
    <div id="map"></div>

    <script>
      var customLabel = {
        restaurant: {
          label: 'R'
        },
        bar: {
          label: 'B'
        }
      };

        function initMap() {

        var origin = {lat: -33.871, lng: 151.197};


        var map = new google.maps.Map(document.getElementById('map'), {
          center: origin,
          zoom: 12
        });

        var clickHandler = new ClickEventHandler(map, origin);

        var infoWindow = new google.maps.InfoWindow;

          // Change this depending on the name of your PHP or XML file
          downloadUrl('https://www.tivahost.com/test/maps/NLPOI.php', function(data) {
            var xml = data.responseXML;
            var markers = xml.documentElement.getElementsByTagName('marker');
            Array.prototype.forEach.call(markers, function(markerElem) {
              var name = markerElem.getAttribute('name');
              var address = markerElem.getAttribute('address');
              var type = markerElem.getAttribute('type');
              var point = new google.maps.LatLng(
                  parseFloat(markerElem.getAttribute('lat')),
                  parseFloat(markerElem.getAttribute('lng')));

              var infowincontent = document.createElement('div');
              var strong = document.createElement('strong');
              strong.textContent = name
              infowincontent.appendChild(strong);
              infowincontent.appendChild(document.createElement('br'));

              var text = document.createElement('text');
              text.textContent = address
              infowincontent.appendChild(text);


              var icon = customLabel[type] || {};


            var iconBase = 'https://maps.google.com/mapfiles/kml/shapes/';
            var icons = {
              restaurant: {
                icon: iconBase + 'parking_lot_maps.png'
              },
              bar: {
                icon: iconBase + 'library_maps.png'
              },
              info: {
                icon: iconBase + 'info-i_maps.png'
              }
            };

              var marker = new google.maps.Marker({
                map: map,
                position: point,
                icon: icons[type].icon,

                label: icon.label
              });
              marker.addListener('click', function() {
                infoWindow.setContent(infowincontent);
                infoWindow.open(map, marker);

              });

            });
          });
        }



      /**
       * @constructor
       */
      var ClickEventHandler = function(map, origin) {
        this.origin = origin;
        this.map = map;
        this.directionsService = new google.maps.DirectionsService;
        this.directionsDisplay = new google.maps.DirectionsRenderer;
        this.directionsDisplay.setMap(map);
//        this.placesService = new google.maps.places.PlacesService(map);
        this.infowindow = new google.maps.InfoWindow;
        this.infowindowContent = document.getElementById('infowindow-content');
        this.infowindow.setContent(this.infowindowContent);

        // Listen for clicks on the map.
        this.map.addListener('click', this.handleClick.bind(this));
      };

      ClickEventHandler.prototype.handleClick = function(event) {
        console.log('You clicked on: ' + event.latLng);
        // If the event has a placeId, use it.
        if (event.placeId) {
          console.log('You clicked on place:' + event.placeId);

          // Calling e.stop() on the event prevents the default info window from
          // showing.
          // If you call stop here when there is no placeId you will prevent some
          // other map click event handlers from receiving the event.
          event.stop();
          this.calculateAndDisplayRoutePlace(event.placeId);
//          this.getPlaceInformation(event.placeId);
        }
        else {
          event.stop();
          this.calculateAndDisplayRoute(event.latLng);          
        }
      };

      ClickEventHandler.prototype.calculateAndDisplayRoutePlace = function(placeId) {
        var me = this;
        this.directionsService.route({
          origin: this.origin,
          destination: {placeId: placeId},
          travelMode: 'WALKING'
        }, function(response, status) {
          if (status === 'OK') {
            me.directionsDisplay.setDirections(response);
          } else {
            window.alert('Directions request failed due to ' + status);
          }
        });
      };

      ClickEventHandler.prototype.calculateAndDisplayRoute = function(latLng) {
        var me = this;
        this.directionsService.route({
          origin: this.origin,
          destination: latLng,
          travelMode: 'WALKING'
        }, function(response, status) {
          if (status === 'OK') {
            me.directionsDisplay.setDirections(response);
          } else {
            window.alert('Directions request failed due to ' + status);
          }
        });
      };      

      ClickEventHandler.prototype.getPlaceInformation = function(placeId) {
        var me = this;
        this.placesService.getDetails({placeId: placeId}, function(place, status) {
          if (status === 'OK') {
            me.infowindow.close();
            me.infowindow.setPosition(place.geometry.location);
            me.infowindowContent.children['place-icon'].src = place.icon;
            me.infowindowContent.children['place-name'].textContent = place.name;
            me.infowindowContent.children['place-id'].textContent = place.place_id;
            me.infowindowContent.children['place-address'].textContent =
                place.formatted_address;
            me.infowindow.open(me.map);
          }
        });
      };



      function downloadUrl(url, callback) {
        var request = window.ActiveXObject ?
            new ActiveXObject('Microsoft.XMLHTTP') :
            new XMLHttpRequest;

        request.onreadystatechange = function() {
          if (request.readyState == 4) {
            request.onreadystatechange = doNothing;
            callback(request, request.status);
          }
        };

        request.open('GET', url, true);
        request.send(null);
      }

      function doNothing() {}
    </script>
    <script async defer
    src="https://maps.googleapis.com/maps/api/js?key=AIzaSyAeuBDdFj7e9OS-gIXIKD51gVd3Ko4hod4&callback=initMap">
    </script>
  </body>
</html>

I know this is not a "proper" answer but here's one way of binding the click event to a marker in similar situation, if you pass in the argument of place , when you create a marker (ie. through search callback): 我知道这不是一个“正确”的答案,但是如果您在创建标记时(例如通过搜索回调)传递了place的参数,则这是在类似情况下将click事件绑定到标记的一种方法:

function createPlaceMarker(place) {
    var placeLoc = place.geometry.location;
    var marker = new google.maps.Marker({
        map: map,
        position: place.geometry.location
    });

    google.maps.event.addListener(marker, 'click', function (event) {
        event.placeId = place.place_id;
        clickHandler.handleClick(event);
    });
}

If you don't have the place of the marker it doesn't make sense to display that info window anyway. 如果您没有标记的place ,则无论如何都不会显示该信息窗口。

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

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