无法读取Google Maps API中未定义的属性“ setMap”

时间:2019-05-24 04:08:09

标签: javascript api google-maps

我正在使用Google Maps API Place Autocomplete Hotel Search构建一个页面,用户可以在其中搜索城市中的酒店,酒吧,餐厅和旅游信息。通过自动完成输入框选择城市,并通过单选按钮选择类别。

当我选择了多个单选按钮类别后,单击“重置”按钮时,会发生问题。控制台中的错误是未捕获的TypeError:无法读取未定义的属性'setMap',这是dropMarker函数上的行标记[i] .setMap(map)。

<section class="section-filter" id="filter">
    <div class="u-center-text u-margin-bottom-small">
        <h2 class="heading-secondary">Filter</h2>
    </div>
    <div class="row">
        <div class="col-sm-6 offset-sm-3">
            <form class="text-center" id="form">
                <div class="form-group">
                    <div id="locationField">
                        <input id="autocomplete" type="text" class="form-control search-input" required />
                    </div>  
                </div>
                <div class="form-group" id="radio-filter">
                    <div class="form-check form-check-inline">
                        <input class="form-check-input" type="radio" name="inlineRadioOptions" id="accommodation">
                        <label class="form-check-label" for="accommodation">
                            <span class="filter-radio-button"></span>
                        Accommodation</label>   
                    </div>
                    <div class="form-check form-check-inline">
                        <input class="form-check-input" type="radio" name="inlineRadioOptions" id="bars">
                        <label class="form-check-label" for="bars">
                            <span class="filter-radio-button"></span>
                        Bars</label>
                    </div>
                    <div class="form-check form-check-inline">
                        <input class="form-check-input" type="radio" name="inlineRadioOptions" id="restaurants">
                        <label class="form-check-label" for="restaurants">
                            <span class="filter-radio-button"></span>
                        Restaurants</label>
                    </div>
                    <div class="form-check form-check-inline">
                        <input class="form-check-input" type="radio" name="inlineRadioOptions" id="attractions">
                        <label class="form-check-label" for="attractions">
                            <span class="filter-radio-button"></span>
                        Attractions</label>
                    </div>
                </div>
                <button id="reset" type="button" class="btn btn-yellow" onclick="resetbtn()">Reset</button>
            </form> 
        </div>  
    </div>
</section>




var map, places, infoWindow;
var markers = [];
var autocomplete;
var countryRestrict = {'country': [] };
var MARKER_PATH = 'https://developers.google.com/maps/documentation/javascript/images/marker_green';
var hostnameRegexp = new RegExp('^https?://.+?/');

//reset the map to initial state, clear markers
function resetbtn() {
  clearMarkers();
  clearResults();
  initMap();
}

// initializes map
function initMap() {
        //sets the initial state of the map, the longtitude, langtitute, zoom, streetview and map controls
        map = new google.maps.Map(document.getElementById('map'), {
          zoom: 3,
          center: {lat: 54.525961, lng: 15.255119},
          styles: styles,
          mapTypeControl: false,
          panControl: true,
          zoomControl: true,
          streetViewControl: true
        });
        //grabs info-content from to generate pop-up window on map for each establishment
        infoWindow = new google.maps.InfoWindow({
          content: document.getElementById('info-content')
        });


        // Create the autocomplete object and associate it with the UI input control.
        // Restrict the search to the default country, and to place type "cities".
        autocomplete = new google.maps.places.Autocomplete(
            /** @type {!HTMLInputElement} */ 
            (
                document.getElementById('autocomplete')), {
                types: ['(cities)'],
                componentRestrictions: countryRestrict
            });
        places = new google.maps.places.PlacesService(map);

        // hides the filter radio-buttons until user clicks on the autocomplete input
        $("#autocomplete").click(function(){
          $("#radio-filter").toggle();
        });

        autocomplete.addListener('place_changed', onPlaceChanged);
        // Add a DOM event listener to react when the user selects a radio-button category
        document.getElementById('accommodation').addEventListener('change', onPlaceChanged);
        document.getElementById('bars').addEventListener('change', onPlaceChanged);
        document.getElementById('restaurants').addEventListener('change', onPlaceChanged);  
        document.getElementById('attractions').addEventListener('change', onPlaceChanged);
      }

      // When the user selects a city, get the place details for the city and
      // zoom the map in on the city.
      function onPlaceChanged() {
        if ($("#accommodation").is(':checked')) {
            var place = autocomplete.getPlace();
            if (place.geometry) {
                map.panTo(place.geometry.location);
            map.setZoom(15);
            searchHotels();
          }
          else {
           $('#autocomplete').attr("placeholder","Enter a city");
         }
       }
       else if ($("#bars").is(':checked')) {
        var place = autocomplete.getPlace();
        if (place.geometry) {
         map.panTo(place.geometry.location);
         map.setZoom(15);
         searchBars();
       }
       else {
         $('#autocomplete').attr("placeholder","Enter a city");
       }
     }
     else if ($("#restaurants").is(':checked')) {
      var place = autocomplete.getPlace();
      if (place.geometry) {
       map.panTo(place.geometry.location);
       map.setZoom(15);
       searchRestaurants();
     }
     else {
       $('#autocomplete').attr("placeholder","Enter a city");
     }
   }
   else if ($("#attractions").is(':checked')) {
    var place = autocomplete.getPlace();
    if (place.geometry) {
     map.panTo(place.geometry.location);
     map.setZoom(15);
     searchAttractions();
   }
   else {
     $('#autocomplete').attr("placeholder","Enter a city");
   }
 }
}
      // Search for hotels in the selected city, within the viewport of the map.
      function searchHotels() {
        var search = {
            bounds: map.getBounds(),
            types: ['lodging']
        };

        places.nearbySearch(search, function(results, status) {
            if (status === google.maps.places.PlacesServiceStatus.OK) {
                clearResults();
                clearMarkers();
            document.getElementById('results-heading').innerHTML = "Results";
            // Create a marker for each hotel found, and
            // assign a letter of the alphabetic to each marker icon.
            for (var i = 0; i < results.length; i++) {
                var markerLetter = String.fromCharCode('A'.charCodeAt(0) + (i % 26));
                var markerIcon = MARKER_PATH + markerLetter + '.png';
              // Use marker animation to drop the icons incrementally on the map.
              markers[i] = new google.maps.Marker({
                position: results[i].geometry.location,
                animation: google.maps.Animation.DROP,
                icon: markerIcon
              });
              // If the user clicks a hotel marker, show the details of that hotel
              // in an info window.
              markers[i].placeResult = results[i];
              google.maps.event.addListener(markers[i], 'click', showInfoWindow);
              setTimeout(dropMarker(i), i * 100);
              addResult(results[i], i);
            }
          }
        });
      }
      // Search for bars and night clubs in the selected city, within the viewport of the map.
      function searchBars() {
        var search = {
            bounds: map.getBounds(),
            types: ['bar', 'night_club']
        };

        places.nearbySearch(search, function(results, status) {
            if (status === google.maps.places.PlacesServiceStatus.OK) {
                clearResults();
                clearMarkers();
            // Create a marker for each bar found, and
            // assign a letter of the alphabetic to each marker icon.
            for (var i = 0; i < results.length; i++) {
                var markerLetter = String.fromCharCode('A'.charCodeAt(0) + (i % 26));
                var markerIcon = MARKER_PATH + markerLetter + '.png';
              // Use marker animation to drop the icons incrementally on the map.
              markers[i] = new google.maps.Marker({
                position: results[i].geometry.location,
                animation: google.maps.Animation.DROP,
                icon: markerIcon
              });
              // If the user clicks a bar marker, show the details of that bar
              // in an info window.
              markers[i].placeResult = results[i];
              google.maps.event.addListener(markers[i], 'click', showInfoWindow);
              setTimeout(dropMarker(i), i * 100);
              addResult(results[i], i);
            }
          }
        });
      }
      // Search for cafes and restaurants in the selected city, within the viewport of the map.
      function searchRestaurants() {
        var search = {
            bounds: map.getBounds(),
            types: ['cafe', 'restaurant']
        };

        places.nearbySearch(search, function(results, status) {
            if (status === google.maps.places.PlacesServiceStatus.OK) {
                clearResults();
                clearMarkers();
            // Create a marker for each restaurant found, and
            // assign a letter of the alphabetic to each marker icon.
            for (var i = 0; i < results.length; i++) {
                var markerLetter = String.fromCharCode('A'.charCodeAt(0) + (i % 26));
                var markerIcon = MARKER_PATH + markerLetter + '.png';
              // Use marker animation to drop the icons incrementally on the map.
              markers[i] = new google.maps.Marker({
                position: results[i].geometry.location,
                animation: google.maps.Animation.DROP,
                icon: markerIcon
              });
              // If the user clicks a restaurant marker, show the details of that restaurant
              // in an info window.
              markers[i].placeResult = results[i];
              google.maps.event.addListener(markers[i], 'click', showInfoWindow);
              setTimeout(dropMarker(i), i * 100);
              addResult(results[i], i);
            }
          }
        });
      }
      // Search for tourist attractions in the selected city, within the viewport of the map.
      function searchAttractions() {
        var search = {
            bounds: map.getBounds(),
            types: ['art_gallery', 'museum', 'park']
        };

        places.nearbySearch(search, function(results, status) {
            if (status === google.maps.places.PlacesServiceStatus.OK) {
                clearResults();
                clearMarkers();
            // Create a marker for each attraction found, and
            // assign a letter of the alphabetic to each marker icon.
            for (var i = 0; i < results.length; i++) {
                var markerLetter = String.fromCharCode('A'.charCodeAt(0) + (i % 26));
                var markerIcon = MARKER_PATH + markerLetter + '.png';
              // Use marker animation to drop the icons incrementally on the map.
              markers[i] = new google.maps.Marker({
                position: results[i].geometry.location,
                animation: google.maps.Animation.DROP,
                icon: markerIcon
              });
              // If the user clicks an attraction marker, show the details of that attraction
              // in an info window.
              markers[i].placeResult = results[i];
              google.maps.event.addListener(markers[i], 'click', showInfoWindow);
              setTimeout(dropMarker(i), i * 100);
              addResult(results[i], i);
            }
          }
        });
      }
      //clears markers from map, empties markers array
      function clearMarkers() {
        for (var i = 0; i < markers.length; i++) {
            if (markers[i]) {
                markers[i].setMap(null);
            }
        }
        markers = [];
      }

      // Set the country restriction based on user input.
      // Also center and zoom the map on the given country.
      function setAutocompleteCountry() {   
        autocomplete.setComponentRestrictions({'country': country});
        map.setCenter(countries[country].center);
        map.setZoom(countries[country].zoom);   
        clearResults();
        clearMarkers();
      }
      // sets markers on map
      function dropMarker(i) {
        return function() {
          markers[i].setMap(map);
        };
      }

      function addResult(result, i) {
        var results = document.getElementById('results');
        var markerLetter = String.fromCharCode('A'.charCodeAt(0) + (i % 26));
        var markerIcon = MARKER_PATH + markerLetter + '.png';

        var tr = document.createElement('tr');
        tr.style.backgroundColor = (i % 2 === 0 ? '#46344E' : '#5A5560');
        tr.onclick = function() {
            google.maps.event.trigger(markers[i], 'click');
        };

        var iconTd = document.createElement('td');
        var nameTd = document.createElement('td');
        var icon = document.createElement('img');
        icon.src = markerIcon;
        icon.setAttribute('class', 'placeIcon');
        icon.setAttribute('className', 'placeIcon');
        var name = document.createTextNode(result.name);
        iconTd.appendChild(icon);
        nameTd.appendChild(name);
        tr.appendChild(iconTd);
        tr.appendChild(nameTd);
        results.appendChild(tr);
      }


      function clearResults() {
        var results = document.getElementById('results');
        while (results.childNodes[0]) {
            results.removeChild(results.childNodes[0]);
        }
      }

      // Get the place details for a hotel. Show the information in an info window,
      // anchored on the marker for the hotel that the user selected.
      function showInfoWindow() {
        var marker = this;
        places.getDetails({placeId: marker.placeResult.place_id},
            function(place, status) {
                if (status !== google.maps.places.PlacesServiceStatus.OK) {
                    return;
                }
                infoWindow.open(map, marker);
                buildIWContent(place);
            });
      }

      // Load the place information into the HTML elements used by the info window.
      function buildIWContent(place) {
        document.getElementById('iw-icon').innerHTML = '<img class="hotelIcon" ' +
        'src="' + place.icon + '"/>';
        document.getElementById('iw-url').innerHTML = '<b><a href="' + place.url +
        '">' + place.name + '</a></b>';
        document.getElementById('iw-address').textContent = place.vicinity;

        if (place.formatted_phone_number) {
            document.getElementById('iw-phone-row').style.display = '';
            document.getElementById('iw-phone').textContent =
            place.formatted_phone_number;
        } else {
            document.getElementById('iw-phone-row').style.display = 'none';
        }

        // Assign a five-star rating to the hotel, using a black star ('&#10029;')
        // to indicate the rating the hotel has earned, and a white star ('&#10025;')
        // for the rating points not achieved.
        if (place.rating) {
            var ratingHtml = '';
            for (var i = 0; i < 5; i++) {
                if (place.rating < (i + 0.5)) {
                    ratingHtml += '&#10025;';
                } else {
                    ratingHtml += '&#10029;';
                }
                document.getElementById('iw-rating-row').style.display = '';
                document.getElementById('iw-rating').innerHTML = ratingHtml;
            }
        } else {
            document.getElementById('iw-rating-row').style.display = 'none';
        }

        // The regexp isolates the first part of the URL (domain plus subdomain)
        // to give a short URL for displaying in the info window.
        if (place.website) {
            var fullUrl = place.website;
            var website = hostnameRegexp.exec(place.website);
            if (website === null) {
                website = 'http://' + place.website + '/';
                fullUrl = website;
            }
            document.getElementById('iw-website-row').style.display = '';
            document.getElementById('iw-website').textContent = website;
        } else {
            document.getElementById('iw-website-row').style.display = 'none';
        }
      }

0 个答案:

没有答案