electron 在初始化Google API之前无法访问“自动完成方向处理程序”

js81xvg6  于 2023-03-06  发布在  Electron
关注(0)|答案(1)|浏览(166)

我正在尝试访问谷歌Map和自动完成API。
下面是我在

Uncaught (in promise) ReferenceError: Cannot access 'AutocompleteDirectionsHandler' before initialization
    at window.initMap (traffic.js:25:5)

下面是我的traffic.HTML文件

<html>
  <head>
    <title>DREAM MIRROR - Traffic </title>
    <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>
    <!-- playground-hide -->
    <script>
      const process = { env: {} };
      process.env.GOOGLE_MAPS_API_KEY =
        "MY_API_KEY";
    </script>
    <!-- playground-hide-end -->

    <link rel="stylesheet" type="text/css" href="traffic.css" />
    <script type="module" src="traffic.js"></script>

    <div class="datetime">
      <div class="time"></div>
      <div class="date"></div>
      
      
    </div>
  </head>
  <style>
    a {

      color: white;
      text-decoration: none;
    }

    a:hover {
      color: #00A0C6;
      text-decoration: none;
      cursor: pointer;
    }
  </style>
  <a href="../index.html">Back</a>
  <body>
    <div >
      <div id="floating-panel">
      <b>Start: </b>
        
        <input type="text" id="origin-input"  placeholder="Enter a location" >

        <b>  <br>
          End: </b>
        <input type="text" id="destination-input"  placeholder="Enter a destination" >
<input type="submit" id="submit">
        
<select id="mode">
  <option value="DRIVING">Driving</option>
  <option value="WALKING">Walking</option>
  <option value="BICYCLING">Bicycling</option>
  <option value="TRANSIT">Transit</option>
</select>
        </div>
    </div>
    <div id="map"></div>
    &nbsp;
    <!-- <div id="warnings-panel"></div> -->
    <div id="directions-panel" style="width: 300px; float: right;"></div>

    <!-- 
      The `defer` attribute causes the callback to execute after the full HTML
      document has been parsed. For non-blocking uses, avoiding race conditions,
      and consistent behavior across browsers, consider loading using Promises
      with https://www.npmjs.com/package/@googlemaps/js-api-loader.
      -->
    <script
      src="https://maps.googleapis.com/maps/api/js?key=MY_API_KEY&callback=initMap&libraries=places&v=weekly" 
      defer
    ></script>
  </body>
</html>

这是我的Javascript文件

let map;
window.initMap = function() {
    map = new google.maps.Map(document.getElementById("map"), {
      zoom: 10,
      center: {
        lat: 29.749907,
        lng: -95.358
      },
    });

    new AutocompleteDirectionsHandler(map);//<--------ERROR HERE

    class AutocompleteDirectionsHandler {
      map;
      originPlaceId;
      destinationPlaceId;
      travelMode;
      directionsService;
      directionsRenderer;
      constructor(map) {
        this.map = map;
        this.originPlaceId = "";
        this.destinationPlaceId = "";
        this.travelMode = google.maps.TravelMode.WALKING;
        this.directionsService = new google.maps.DirectionsService();
        this.directionsRenderer = new google.maps.DirectionsRenderer();
        this.directionsRenderer.setMap(map);
    
        const originInput = document.getElementById("origin-input");
        const destinationInput = document.getElementById("destination-input");
        const modeSelector = document.getElementById("mode-selector");
        // Specify just the place data fields that you need.
        const originAutocomplete = new google.maps.places.Autocomplete(
          originInput,
          { fields: ["place_id"] }
        );
        // Specify just the place data fields that you need.
        const destinationAutocomplete = new google.maps.places.Autocomplete(
          destinationInput,
          { fields: ["place_id"] }
        );
    
        this.setupClickListener(
          "changemode-walking",
          google.maps.TravelMode.WALKING
        );
        this.setupClickListener(
          "changemode-transit",
          google.maps.TravelMode.TRANSIT
        );
        this.setupClickListener(
          "changemode-driving",
          google.maps.TravelMode.DRIVING
        );
        this.setupPlaceChangedListener(originAutocomplete, "ORIG");
        this.setupPlaceChangedListener(destinationAutocomplete, "DEST");
        this.map.controls[google.maps.ControlPosition.TOP_LEFT].push(originInput);
        this.map.controls[google.maps.ControlPosition.TOP_LEFT].push(
          destinationInput
        );
        this.map.controls[google.maps.ControlPosition.TOP_LEFT].push(modeSelector);
      }
      // Sets a listener on a radio button to change the filter type on Places
      // Autocomplete.
      setupClickListener(id, mode) {
        const radioButton = document.getElementById(id);
    
        radioButton.addEventListener("click", () => {
          this.travelMode = mode;
          this.route();
        });
      }
      setupPlaceChangedListener(autocomplete, mode) {
        autocomplete.bindTo("bounds", this.map);
        autocomplete.addListener("place_changed", () => {
          const place = autocomplete.getPlace();
    
          if (!place.place_id) {
            window.alert("Please select an option from the dropdown list.");
            return;
          }
    
          if (mode === "ORIG") {
            this.originPlaceId = place.place_id;
          } else {
            this.destinationPlaceId = place.place_id;
          }
    
          this.route();
        });
      }
      route() {
        if (!this.originPlaceId || !this.destinationPlaceId) {
          return;
        }
    
        const me = this;
    
        this.directionsService.route(
          {
            origin: { placeId: this.originPlaceId },
            destination: { placeId: this.destinationPlaceId },
            travelMode: this.travelMode,
          },
          (response, status) => {
            if (status === "OK") {
              me.directionsRenderer.setDirections(response);
            } else {
              window.alert("Directions request failed due to " + status);
            }
          }
        );
      }
    }
    
    window.initMap = initMap;

我尝试了这里的解决方案Google Maps: Uncaught ReferenceError: google is not defined异步加载我的js文件之前,谷歌Map脚本正在处理添加异步延迟,但它没有解决这个问题。
我注解了代码中发生错误的位置,下面是一个屏幕截图。

xeufq47z

xeufq47z1#

有一个语法错误(在window.initMap=initMap;之前的末尾缺少})。另一个问题是您在声明AutocompleteDirectionsHandler之前使用了它。在类定义之后调用构造函数可以修复该错误。

    • 代码片段:**
let map;

window.initMap = function() {

  map = new google.maps.Map(document.getElementById("map"), {
    zoom: 10,
    center: {
      lat: 29.749907,
      lng: -95.358
    },
  });

  class AutocompleteDirectionsHandler {
    map;
    originPlaceId;
    destinationPlaceId;
    travelMode;
    directionsService;
    directionsRenderer;
    constructor(map) {
      this.map = map;
      this.originPlaceId = "";
      this.destinationPlaceId = "";
      this.travelMode = google.maps.TravelMode.WALKING;
      this.directionsService = new google.maps.DirectionsService();
      this.directionsRenderer = new google.maps.DirectionsRenderer();
      this.directionsRenderer.setMap(map);

      const originInput = document.getElementById("origin-input");
      const destinationInput = document.getElementById("destination-input");
      const modeSelector = document.getElementById("mode-selector");
      // Specify just the place data fields that you need.
      const originAutocomplete = new google.maps.places.Autocomplete(
        originInput, {
          fields: ["place_id"]
        }
      );
      // Specify just the place data fields that you need.
      const destinationAutocomplete = new google.maps.places.Autocomplete(
        destinationInput, {
          fields: ["place_id"]
        }
      );
      this.setupPlaceChangedListener(originAutocomplete, "ORIG");
      this.setupPlaceChangedListener(destinationAutocomplete, "DEST");
      this.map.controls[google.maps.ControlPosition.TOP_LEFT].push(originInput);
      this.map.controls[google.maps.ControlPosition.TOP_LEFT].push(
        destinationInput
      );
      this.map.controls[google.maps.ControlPosition.TOP_LEFT].push(modeSelector);
    }
    // Sets a listener on a radio button to change the filter type on Places
    // Autocomplete.
    setupClickListener(id, mode) {
      const radioButton = document.getElementById(id);

      radioButton.addEventListener("click", () => {
        this.travelMode = mode;
        this.route();
      });
    }
    setupPlaceChangedListener(autocomplete, mode) {
      autocomplete.bindTo("bounds", this.map);
      autocomplete.addListener("place_changed", () => {
        const place = autocomplete.getPlace();

        if (!place.place_id) {
          window.alert("Please select an option from the dropdown list.");
          return;
        }

        if (mode === "ORIG") {
          this.originPlaceId = place.place_id;
        } else {
          this.destinationPlaceId = place.place_id;
        }

        this.route();
      });
    }
    route() {
      if (!this.originPlaceId || !this.destinationPlaceId) {
        return;
      }

      const me = this;

      this.directionsService.route({
          origin: {
            placeId: this.originPlaceId
          },
          destination: {
            placeId: this.destinationPlaceId
          },
          travelMode: this.travelMode,
        },
        (response, status) => {
          if (status === "OK") {
            me.directionsRenderer.setDirections(response);
          } else {
            window.alert("Directions request failed due to " + status);
          }
        }
      );
    }
  }

  new AutocompleteDirectionsHandler(map); //<--------ERROR HERE
}

window.initMap = initMap;
<html>

<head>
  <title>DREAM MIRROR - Traffic </title>
  <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>
</head>
<style>
  a {
    color: white;
    text-decoration: none;
  }
  
  a:hover {
    color: #00A0C6;
    text-decoration: none;
    cursor: pointer;
  }
  
  html,
  body {
    height: 100%;
    width: 100%;
    padding: 0;
    margins: 0;
  }
  
  #map {
    height: 80%;
    width: 100%;
  }
</style>
<a href="../index.html">Back</a>

<body>
  <div>
    <div id="floating-panel">
      <b>Start: </b>

      <input type="text" id="origin-input" placeholder="Enter a location">

      <b>  <br>
          End: </b>
      <input type="text" id="destination-input" placeholder="Enter a destination">
      <input type="submit" id="submit">

      <select id="mode">
        <option value="DRIVING">Driving</option>
        <option value="WALKING">Walking</option>
        <option value="BICYCLING">Bicycling</option>
        <option value="TRANSIT">Transit</option>
      </select>

    </div>
  </div>
  <div id="map"></div>
  &nbsp;
  <!-- <div id="warnings-panel"></div> -->
  <div id="directions-panel" style="width: 300px; float: right;"></div>

  <!-- 
      The `defer` attribute causes the callback to execute after the full HTML
      document has been parsed. For non-blocking uses, avoiding race conditions,
      and consistent behavior across browsers, consider loading using Promises
      with https://www.npmjs.com/package/@googlemaps/js-api-loader.
      -->
  <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap&libraries=places&v=weekly" defer></script>

</body>

</html>

相关问题