简体   繁体   中英

How to show Google Map API only after it has completely loaded?

I'm trying to use the Places search functionality of Google Maps API.

My problem is, the search box shifts and the height of the API container changes after the map is completely loaded.

I've made a demonstration of the problem. Try refreshing the page and you'll observe the above mentioned behaviour.

I found similar questions and the suggestions were --

google.maps.event.addListenerOnce(map, 'idle', function() {
   google.maps.event.trigger(map, 'resize');
});

or

window.onload = map_initialize;

However, neither of them seem to solve this shift behaviour.

One option would be to set the input to display:none , add it to the map on the idle event, then display it.

function initAutocomplete() {
  var map = new google.maps.Map(document.getElementById('map'), {
    center: {
        lat: -33.8688,
        lng: 151.2195
    },
    zoom: 13,
    mapTypeId: google.maps.MapTypeId.ROADMAP
  });
  // Create the search box and link it to the UI element.
  var input = document.getElementById('pac-input');
  var searchBox = new google.maps.places.SearchBox(input);    
  map.controls[google.maps.ControlPosition.TOP_LEFT].push(input);
  google.maps.event.addListenerOnce(map, 'idle', function() {
    input.style.display = "block";
  });

proof of concept fiddle

code snippet:

 // This example adds a search box to a map, using the Google Place Autocomplete // feature. People can enter geographical searches. The search box will return a // pick list containing a mix of places and predicted search terms. function initAutocomplete() { var map = new google.maps.Map(document.getElementById('map'), { center: { lat: -33.8688, lng: 151.2195 }, zoom: 13, mapTypeId: google.maps.MapTypeId.ROADMAP }); // Create the search box and link it to the UI element. var input = document.getElementById('pac-input'); var searchBox = new google.maps.places.SearchBox(input); map.controls[google.maps.ControlPosition.TOP_LEFT].push(input); google.maps.event.addListenerOnce(map, 'idle', function() { input.style.display = "block"; }); // Bias the SearchBox results towards current map's viewport. map.addListener('bounds_changed', function() { searchBox.setBounds(map.getBounds()); }); var markers = []; // Listen for the event fired when the user selects a prediction and retrieve // more details for that place. searchBox.addListener('places_changed', function() { var places = searchBox.getPlaces(); if (places.length == 0) { return; } // Clear out the old markers. markers.forEach(function(marker) { marker.setMap(null); }); markers = []; // For each place, get the icon, name and location. var bounds = new google.maps.LatLngBounds(); places.forEach(function(place) { var icon = { url: place.icon, size: new google.maps.Size(71, 71), origin: new google.maps.Point(0, 0), anchor: new google.maps.Point(17, 34), scaledSize: new google.maps.Size(25, 25) }; // Create a marker for each place. markers.push(new google.maps.Marker({ map: map, icon: icon, title: place.name, position: place.geometry.location })); if (place.geometry.viewport) { // Only geocodes have viewport. bounds.union(place.geometry.viewport); } else { bounds.extend(place.geometry.location); } }); map.fitBounds(bounds); }); } google.maps.event.addDomListener(window, 'load', initAutocomplete); 
 html, body { height: 100%; margin: 0; padding: 0; } #map { height: 100%; } .controls { margin-top: 10px; border: 1px solid transparent; border-radius: 2px 0 0 2px; box-sizing: border-box; -moz-box-sizing: border-box; height: 32px; outline: none; box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3); } #pac-input { background-color: #fff; font-family: Roboto; font-size: 15px; font-weight: 300; margin-left: 12px; padding: 0 11px 0 13px; text-overflow: ellipsis; width: 300px; } #pac-input:focus { border-color: #4d90fe; } .pac-container { font-family: Roboto; } #type-selector { color: #fff; background-color: #4d90fe; padding: 5px 11px 0px 11px; } #type-selector label { font-family: Roboto; font-size: 13px; font-weight: 300; } #target { width: 345px; } 
 <script src="https://maps.googleapis.com/maps/api/js?libraries=places"></script> <input id="pac-input" class="controls" type="text" placeholder="Search Box" style="display:none"> <div id="map"></div> 

You can simply use the defer attribute for your <script> tag where you loading the google maps JS api , and a callback function to initialize your map.

 <!DOCTYPE html> <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>Google map demo</title> <style type="text/css"> html, body, #map_canvas { width: 100%; height: 700px; margin: 0; padding: 0; } .infowindow * { font-size: 90%; margin: 0 } </style> <script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?callback=initialize" defer></script> </head> <body> <div id="map_canvas"></div> </body> <script type="text/javascript"> function initialize() { alert("map api loaded"); // initialize map var myOptions = { zoom: 2, center: new google.maps.LatLng(37.422104808, -122.0838851) }; map = new google.maps.Map(document.getElementById("map_canvas"), myOptions); } </script> </html> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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