如果异步,Google地图无法加载

时间:2017-05-31 18:44:02

标签: javascript jquery google-maps knockout.js

每当我尝试异步加载谷歌地图时,无法加载,直到我多次重新加载页面。从代码中删除异步运行良好。 我已经使用了knockout.js和Foursquare API进行工作。

//strict
//JavaScript file
$(document).ready(function() {

  //initialize map
  var map;
  //if no error occours
  if (typeof google != "undefined") {
    map = new google.maps.Map(document.getElementById('display-area'), {
      center: new google.maps.LatLng(30.4100, 77.98000),
      zoom: 11,

    });

  } //else the error message will be displayed
  else {
    $('#error').css('display', 'block'); //error handling if map loading fails
    $('#error').css('color', 'red'); //error handling color set to red 
    $('#display_area').css('display', 'none'); //map loading fails

  }
  //display list of places
  $('#view-list-toggle').click(function() {
    var list = $('#view-list');
    //view-list is initially set to display:none, when any marker is clicked it has to be displayed
    list.css('display', 'block');

  });



  //array of locations where the markers are to be created
  //loc is the location

  var locDetails = [{
      loc: new google.maps.LatLng(30.416333, 77.968585),
      title: "UPES Dehradun",
      details: '<b>University of Petroleum and Energy Studies, Dehradun. My place!:)</b><br><img src="images/upes.jpg" width=100%>',
      venues: "4e61e0d1e4cdf1e2bf0ddd66",
      searchOptions: ['college', 'petroleum']
    }, //venues are used in foursquareURL to get the location and rating of the place.
    //searchOptions provide a easier search,
    {
      loc: new google.maps.LatLng(30.34266547538908, 78.0602590943995),
      title: "Silver City Multiplex",
      details: '<b>Silver City Multiplex</b><br>A perfect shopping and movie hall for fun<br><img src="images/sc.jpg" width=100%>',
      venues: "4efad823469012b8c3fcad8c",
      searchOptions: ['mall', 'shopping']
    },
    {
      loc: new google.maps.LatLng(30.33308670383727, 77.99534667810693),
      title: "Forest research institute",
      details: '<b>The Forest Research Institute</b><br> It is an institute of the Indian Council of Forestry Research and Education and is a premier institution in the field of forestry research in India.<br><img src="images/fri.jpg" width=100%>',
      venues: "56c95d90cd10173286d99b0c",
      searchOptions: ['institute', 'places']
    },
    {

      loc: new google.maps.LatLng(30.3572660, 78.0166512),
      title: "Tapkeshwar Mandir",
      details: '<b>Tapkeshwar Mandir</b><br>Water drips from the cave walls of this famous, tranquil Hindu temple honoring Lord Shiva<br><img src="images/tap.jpg" width=100%>',
      venues: "516fc256e4b03bca88777ab4",
      searchOptions: ['places', 'temple']
    },
    {

      loc: new google.maps.LatLng(30.334597469681178, 77.98139035061027),
      title: "IMA",
      details: '<b>The Indian Military Academy</b><br> Dehradun is the officer training Academy of the Indian Army. IMA was established in 1932<br><img src="images/ima.jpg" width=100%>',
      venues: "4d8f0723835b530cbf6fa5b6",
      searchOptions: ['acedemy', 'army']
    },
    {
      loc: new google.maps.LatLng(30.340292, 77.952410),
      title: "Uttaranchal University",
      details: '<b>Uttaranchal University</b><br>It is a State Private university established by the Government of Uttarakhand and approverd by UGC.<br><img src="images/uti.jpg" width=100%>',
      venues: "57f4b07d498e1f07ac71068e",
      searchOptions: ['university', 'study']

    },
    {
      loc: new google.maps.LatLng(30.322101132963066, 78.00289561203648),
      title: "Big Cinemas",
      details: '<b>Carnival Cinemas-Vikas mall</b><br>A mall, where you can easily find fun stuffs like food and movies<br><img src="images/car.png" width=100%>',
      venues: "50cc6304e4b0af445c617e6f",
      searchOptions: ['movie', 'shop']

    },
    {
      loc: new google.maps.LatLng(30.409601848936052, 77.97009795321478),
      title: "Sai Mandir",
      details: '<b>Temple</b><br>A hindu temple near university of petroleum and energy studies',
      venues: "513886f1e4b019e1c4745c8b",
      searchOptions: ['temple', 'temples']

    },
    {
      loc: new google.maps.LatLng(30.488112761304816, 78.03671992371376),
      title: "Kempty Fall",
      details: '<b>Kempty Fall</b><br>A very Calm and Soothing place as a family picnic destination.<br><img src="images/kempty.jpg" width=100%>',
      venues: "4e8fe25d02d5ee38b690c60c",
      searchOptions: ['water', 'fall']

    },
    {
      loc: new google.maps.LatLng(30.459536, 78.020681),
      title: "George everest",
      details: '<b>George everest</b><br>Beautiful location peace of mind relaxing place worth a visit<br><img src="images/ge.jpg" width=100%>',
      venues: "4fba04bce4b09a2fd4f5b957",
      searchOptions: ['hill', 'mountains']

    }


  ];



  function MVM() {
    var temp = []; //will be used to store the markers
    var self = this;

    for (var j = 0; j < locDetails.length; j++)
      temp.push(new finalMarker(locDetails[j], self)); //

    self.query = ko.observable('');
    self.markers = ko.observableArray(temp);
    self.fName = ko.observable('');
    self.fRating = ko.observable('');

    self.kill = function() {
      for (var i = 0; i < self.markers().length; i++)
        self.markers()[i].startState();
    };

    self.searchMarkers = function() {
      // find a list of markers that match the string
      var search_matches = [];
      //a list of markers that do not matches and needs to be hidden
      var search_not_match = [];
      var query = self.query();
      for (var k = 0; k < self.markers().length; k++) {
        var mrkr = self.markers()[k];
        if (mrkr.matches(query))
          search_matches.push(mrkr);
        else
          search_not_match.push(mrkr);
      }

      for (i = 0; i < search_matches.length; i++)
        search_matches[i].matchesSearch();
      //if search matches then the list is set to be visible;
      for (i = 0; i < search_not_match.length; i++)
        search_not_match[i].doNotMatch();
      //all the remaining is set to be hidden


    };

    self.selectItem = function(item) {
      item.selected();
    };
  }

  function finalMarker(marker_info, model) {
    var self = this;
    self.model = model;
    self.title = marker_info.title;
    self.venues = marker_info.venues;
    self.text = ko.observable(marker_info.details);
    self.searchOptions = marker_info.searchOptions;
    var infoParts = self.text().split(" "); //splits the infopart and add it to searchOptions, it will help in making the search more easier to users.
    for (var i = 0; i < infoParts.length; i++)
      self.searchOptions.push(infoParts[i].toLowerCase());

    var titleParts = self.title.split(" "); //splits the title and add it to searchOptions, it will help in making the search more easier to users.
    for (i = 0; i < titleParts.length; i++)
      self.searchOptions.push(titleParts[i].toLowerCase());


    self.infowindow = new google.maps.InfoWindow({
      content: self.text()
    });
    self.googleMarker = new google.maps.Marker({
      position: marker_info.loc,
      title: marker_info.title,
      map: map,
      animation: google.maps.Animation.DROP
    });


    //when any one of the markers on the map is clicked then this function is called.
    google.maps.event.addListener(self.googleMarker, 'click', function() {
      self.selected();
      self.toggleBounce();
      //animate the markers when loaded.
      function toggleBounce() {
        if (marker.getAnimation() !== null) {
          marker.setAnimation(null);
        } else {
          marker.setAnimation(google.maps.Animation.BOUNCE);
        }
      }

    });

    self.selected = function() {
      // kills/closes all the other window popups
      model.kill();
      self.clicked();

      $('#four-view').css('display', 'block');
      //url for foursquare
      var foursquareUrl = 'https://api.foursquare.com/v2/venues/' + self.venues + '?v=20170503&' + 'client_id=' + 'I5E3UJKIUR03YMFPIC0DEML402JJLEH2ZBN2MJMVY1CERFZA' + '&client_secret=' + 'J10CMGOLXC24EJTBBMW5DUD3O5DDXJ5E5Y134MAFQG15AYNQ';
      model.fRating('');

      //foursquare api settingz
      //id = "I5E3UJKIUR03YMFPIC0DEML402JJLEH2ZBN2MJMVY1CERFZA";
      //Secret = "J10CMGOLXC24EJTBBMW5DUD3O5DDXJ5E5Y134MAFQG15AYNQ";


      model.fName('');

      //ajax async. loads the data when the marker is clicked
      $.ajax({
          url: foursquareUrl
        }).done(
          function(response) {
            var res = response.response.venue;
            model.fName(res.name);
            model.fRating(res.rating);
            if (!res.rating) {
              model.fRating('not yet rated');
            } else
              model.fRating('rated as ' + res.rating);

          })
        .error(function() {
          model.fName('error');
          model.fRating('error');
        });
    };


    self.matches = function(q) {
      return $.inArray(q.toLowerCase(), self.searchOptions) != -1;
    };


    self.matchesSearch = function() {
      self.isHidden(false);
      self.googleMarker.setVisible(true);
      self.infowindow.open(map, self.googleMarker);
      $('#four-view').css('display', 'none');
    };



    self.startState = function() {
      self.isHidden(false);
      self.googleMarker.setVisible(true);
      self.infowindow.close();
      $('#four-view').css('display', 'none');
    };



    self.doNotMatch = function() {
      self.isHidden(true);
      self.googleMarker.setVisible(false);
      self.infowindow.close();
      $('#four-view').css('display', 'none');
    };

    self.clicked = function() {
      self.isHidden(false);
      self.googleMarker.setVisible(true);
      self.googleMarker.setAnimation(google.maps.Animation.BOUNCE);
      setTimeout(function() {
        self.googleMarker.setAnimation(null);
      }, 1400);
      self.infowindow.open(map, self.googleMarker);
    };

    self.isHidden = ko.observable(false);
  }



  ko.applyBindings(new MVM());

});
html,
body {
  height: 99%;
  margin: 0px;
  padding-left: 10px;
  padding-right: 10px;
  background: linear-gradient(27deg, #151515 5px, transparent 5px) 0 5px, linear-gradient(207deg, #151515 5px, transparent 5px) 10px 0px, linear-gradient(27deg, #222 5px, transparent 5px) 0px 10px, linear-gradient(207deg, #222 5px, transparent 5px) 10px 5px, linear-gradient(90deg, #1b1b1b 10px, transparent 10px), linear-gradient(#1d1d1d 25%, #1a1a1a 25%, #1a1a1a 50%, transparent 50%, transparent 75%, #242424 75%, #242424);
  background-color: #131313;
  background-size: 20px 20px;
}

input {
  width: 20%;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.45), 0 1px 3px rgba(0, 0, 0, 0.44);
  border: 1px solid black;
  position: relative;
  padding-bottom: 2px;
  margin-bottom: 2px;
}

h1 {
  color: white;
}

@media only screen and (min-width: 506px) {
  #view-list {
    display: block !important;
  }
}

#display-area {
  height: 100%;
  width: 100%;
  margin: 5px;
  padding: 5px;
}

#view-list {
  top: 30%;
  right: 0px;
  position: absolute;
  font-weight: bold;
  color: white;
  background: linear-gradient(27deg, #151515 5px, transparent 5px) 0 5px, linear-gradient(207deg, #151515 5px, transparent 5px) 10px 0px, linear-gradient(27deg, #222 5px, transparent 5px) 0px 10px, linear-gradient(207deg, #222 5px, transparent 5px) 10px 5px, linear-gradient(90deg, #1b1b1b 10px, transparent 10px), linear-gradient(#1d1d1d 25%, #1a1a1a 25%, #1a1a1a 50%, transparent 50%, transparent 75%, #242424 75%, #242424);
  background-color: #131313;
  background-size: 20px 20px;
  box-shadow: 10px 4px 13px rgba(0, 0, 0, 0.45), 5px 10px 10px rgba(0, 0, 0, 0.64);
  border: 1px solid black;
}

#four-view {
  padding: 5px;
  color: grey;
  display: none;
  text-align: center;
  -ms-transform: translateY(-50%);
  -webkit-transform: translateY(-50%);
  transform: translateY(-50%);
}

.hidden {
  display: none;
}

.list-item:hover {
  background-color: grey;
}

#view-list-toggle {
  display: none;
  background-color: grey;
  padding: 5px;
}

@media only screen and (max-width: 528px) {
  h1 {
    display: none;
  }
  #display-area {
    height: 100%;
  }
  #four-view {
    padding-top: 10px;
    margin-top: 10px;
  }
  #view-list {
    font-size: 10px;
  }
}
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">

<head>
  <title>Neighbourhood</title>
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <link rel="stylesheet" type="text/css" href="css/main.css" />
  <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDy2Gh9s53u0nitvdqECa5cevawqiBwkP0&callback=initMap"></script>
</head>

<body bgcolor="grey">

  <h1 align="center">Neighbourhood Project - Udacity</h1>

  <form action="/" align="right">
    <input data-bind="value: query" maxlength="100" />
    <button data-bind="click: searchMarkers">Search List</button>
  </form>


  <div id="four-view" class="rating">
    <strong data-bind="text: fName"></strong> is <strong data-bind="text: fRating" style="color: white;"></strong> by foursquare.
  </div>



  <div id="view-list-toggle">List View</div>
  <div id="display-area"></div>

  <div id="view-list">
    <table>
      <tbody data-bind="foreach: markers()">
        <tr data-bind="click: $root.selectItem">
          <td data-bind="text: title, css : { hidden : isHidden() }" class='list-item'></td>
        </tr>
      </tbody>
    </table>
  </div>




  <div id="error" style="display : none; color : green">Oops!! The map could not be loaded. Please check your connection.</div>

  <script type='text/javascript' src='js/knockout-3.3.0.js'></script>
  <script type='text/javascript' src='js/jquery-2.1.3.min.js'></script>
  <script type="text/javascript" src="js/main.js"></script>

</body>

</html>

1 个答案:

答案 0 :(得分:0)

如果您使用的是jQuery,则可以使用jQuery的$.getScript()方法异步加载谷歌地图。

以下是您将如何执行此操作的示例:

function initMap() {
  // logic for creating map
}

var mapsUrl = "https://maps.googleapis.com/maps/api/js?key=" + "Your_API_KEY" + "&v=3";

$.getScript(mapsUrl)
  .done(function() {
    initMap();
  })
  .fail(function() {
    console.log('Error: Map failed to load.');
  });