未定义API链接的回调函数

时间:2018-04-14 01:46:16

标签: javascript node.js google-maps handlebars.js

我正在使用Node.js制作一个简单的谷歌地图。它仅在我直接在script标记中提供代码时才起作用。当我尝试将它链接到外部文件时,它不起作用。

必须如何完成所有事情都不在范围之外。

我的浏览器控制台: enter image description here

我的项目设置

enter image description here

我的HTML

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Maps</title>
</head>
<body>
  <div id="map"></div>
<script src=".././public/javascripts/main.js"></script>
<script src="https://maps.googleapis.com/maps/api/js?key=mykey&libraries=places&callback=initMap" async defer></script>
</body>
</html>

我的map代码。它的工作正常,但问题是将它链接到主HTML页面。

let google = window.google; <-- didnt help -->
let map, infoWindow;
function initMap() {
   map = new google.maps.Map(document.getElementById('map'), {
      center: {lat: -34.397, lng: 150.644},
      zoom: 18,
      mapTypeControl: true,
      mapTypeId: google.maps.MapTypeId.HYBRID, // once the page loaded the user see a {satellite} map type of his location.
      mapTypeControlOptions: {
        style: google.maps.MapTypeControlStyle.DEFAULT,
        mapTypeIds: ['satellite','roadmap','hybrid']
      }
    });

    google.maps.event.addDomListener(window, 'load', initMap);

  infoWindow = new google.maps.InfoWindow;

        // Try HTML5 geolocation. get the user current location.
      if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(function(position) {
          let pos = {
            lat: position.coords.latitude,
            lng: position.coords.longitude
          };

          infoWindow.setPosition(pos);
          map.setCenter(pos);

          let centerControlDiv = document.createElement('div'); // creating {Center Map} button
          let centerControl = new CenterControl(centerControlDiv, map, pos);
           /* passing the {div} element we just created.
            and the {map} variable that contain the actual map.
            with the {pos} variable that contain the user location
            {lat,lng}.
          */
          centerControlDiv.index = 1;  // positioning the {My location} button
          centerControlDiv.style['padding-top'] = '10px'; // styling the {My location} button
          map.controls[google.maps.ControlPosition.BOTTOM_CENTER].push(centerControlDiv); // positioned into RIGHT-CENTER

      function CenterControl(controlDiv, map, center) {
            // We set up a variable for this since we're adding event listeners
            // later.
            let control = this;
            let marker = new google.maps.Marker({ // a red marker placed on the user location.
                  position: pos,
                  map: map,
                  title: 'Your current location',
                  animation: google.maps.Animation.DROP,
                  draggable:true,
                  id: 'marker'
            });

            // Set the center property upon construction
            control.center_ = center;
            controlDiv.style.clear = 'both';

            // Set CSS for the control border
            let goCenterUI = document.createElement('div');
            goCenterUI.id = 'goCenterUI';
            goCenterUI.title = 'Click to recenter the map';
            controlDiv.appendChild(goCenterUI);

            // Set CSS for the control interior
            let goCenterText = document.createElement('div');
            goCenterText.id = 'goCenterText';
            goCenterText.innerHTML = 'My location';
            goCenterUI.appendChild(goCenterText);

            // Set up the click event listener for 'My location': Set the center of
            // the map
            // to the current center of the control.
            goCenterUI.addEventListener('click', () => {
              let currentCenter = control.getCenter();
              map.setCenter(currentCenter);

              marker.setAnimation(google.maps.Animation.BOUNCE); // make the marker BOUNCE when {my location} button is pressed.
              setTimeout(()=> marker.setAnimation(null), 1500); // stop bouncing after 1.5seconds.
            });

            marker.addListener('drag', function(){ // while dragging the marker a popup notify the user dropping will change location.
                infoWindow.setContent('Drop to set a new location');
                infoWindow.open(map,marker);
                console.log('dragging..');
            });

            // change the location based on where the user drag & dropped the marker.
            marker.addListener('dragend', () => {
                infoWindow.close();
                let newCenter = map.getCenter();
                control.setCenter(marker.position); // set the location to the marker's position.
            });

            // marker BOUNCE when clicked then stop after 1.5seconds.
            marker.addListener('click', ()=>{
              if (marker.getAnimation() !== null){
                marker.setAnimation(null);
              } else{
                marker.setAnimation(google.maps.Animation.BOUNCE);
                setTimeout(()=> marker.setAnimation(null), 1500);
              }
              // open a popup to notify the user changing location is by dragging the marker.
              infoWindow.setContent('Drag to change your location');
              infoWindow.open(map,marker);
              setTimeout(()=>infoWindow.close(), 1100);
            });

          let requestPlacesDetails = {
            placeId : 'ChIJN1t_tDeuEmsRUsoyG83frY4'
          }

          let PlacesDetails = (results, status) =>{
            if(status == google.maps.places.PlacesServiceStatus.OK){
              for(let i = 0; i < results.length; i++){
                console.log(results[i]);
              }
            }

          }

          let service = new google.maps.places.PlacesService(map);

          service.getDetails(requestPlacesDetails, PlacesDetails); // get details about every place nearby the user location.

            /**
            * Define a property to hold the center state.
            * @private
            */
            CenterControl.prototype.center_ = null;

            /**
            * Gets the map center.
            * @return {?google.maps.LatLng}
            */
            CenterControl.prototype.getCenter = function() {
              return this.center_;
            };

            /**
            * Sets the map center.
            * @param {?google.maps.LatLng} center
            */
            CenterControl.prototype.setCenter = function(center) {
              this.center_ = center;
            };

          }
        }, function() {
          handleLocationError(true, infoWindow, map.getCenter());
        });
      } else {
        // Browser doesn't support Geolocation
        handleLocationError(false, infoWindow, map.getCenter());
      }
    }


    function handleLocationError(browserHasGeolocation, infoWindow, pos) {
      infoWindow.setPosition(pos);
      infoWindow.setContent(browserHasGeolocation ?
                            'Error: The Geolocation service failed.' :
                            'Error: Your browser doesn\'t support geolocation.');
      infoWindow.open(map);
    }

  export {initMap}

编辑并非它没有加载。因为如果我这样做: - everthing工作正常并且符合预期。所以它更像是在外面没有重新认识js文件。我正在使用hbs(把手)来获取HTML代码。

<html>
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Maps</title>
</head>
<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;
    }

  #goCenterUI {
    background-color: #fff;
    border: 2px solid #fff;
    border-radius: 3px;
    box-shadow: 0 2px 6px rgba(0,0,0,.3);
    cursor: pointer;
    float: left;
    margin-bottom: 22px;
    text-align: center;
  }

  #goCenterText {
    color: rgb(25,25,25);
    font-family: Roboto,Arial,sans-serif;
    font-size: 15px;
    line-height: 25px;
    padding-left: 5px;
    padding-right: 5px;
    user-select: none;
  }
  #setCenterUI {
    margin-left: 12px;
  }
</style>
<body>
  <div id="map"></div>
  <p>TESTTESTEST</p>
</body>
<script src="https://maps.googleapis.com/maps/api/js?key=mykey&libraries=places&callback=initMap" async defer></script>
<script type='application/javascript'>


let map, infoWindow;

function initMap() {
   map = new google.maps.Map(document.getElementById('map'), {
      center: {lat: -34.397, lng: 150.644},
      zoom: 18,
      mapTypeControl: true,
      mapTypeId: google.maps.MapTypeId.HYBRID, // once the page loaded the user see a {satellite} map type of his location.
      mapTypeControlOptions: {
        style: google.maps.MapTypeControlStyle.DEFAULT,
        mapTypeIds: ['satellite','roadmap','hybrid']
      }
    });


  infoWindow = new google.maps.InfoWindow;

        // Try HTML5 geolocation. get the user current location.
      if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(function(position) {
          let pos = {
            lat: position.coords.latitude,
            lng: position.coords.longitude
          };

          infoWindow.setPosition(pos);
          map.setCenter(pos);

          let centerControlDiv = document.createElement('div'); // creating {Center Map} button
          let centerControl = new CenterControl(centerControlDiv, map, pos);
           /* passing the {div} element we just created.
            and the {map} variable that contain the actual map.
            with the {pos} variable that contain the user location
            {lat,lng}.
          */
          centerControlDiv.index = 1;  // positioning the {My location} button
          centerControlDiv.style['padding-top'] = '10px'; // styling the {My location} button
          map.controls[google.maps.ControlPosition.BOTTOM_CENTER].push(centerControlDiv); // positioned into RIGHT-CENTER

      function CenterControl(controlDiv, map, center) {
            // We set up a variable for this since we're adding event listeners
            // later.
            let control = this;
            let marker = new google.maps.Marker({ // a red marker placed on the user location.
                  position: pos,
                  map: map,
                  title: 'Your current location',
                  animation: google.maps.Animation.DROP,
                  draggable:true,
                  id: 'marker'
            });

            // Set the center property upon construction
            control.center_ = center;
            controlDiv.style.clear = 'both';

            // Set CSS for the control border
            let goCenterUI = document.createElement('div');
            goCenterUI.id = 'goCenterUI';
            goCenterUI.title = 'Click to recenter the map';
            controlDiv.appendChild(goCenterUI);

            // Set CSS for the control interior
            let goCenterText = document.createElement('div');
            goCenterText.id = 'goCenterText';
            goCenterText.innerHTML = 'My location';
            goCenterUI.appendChild(goCenterText);

            // Set up the click event listener for 'My location': Set the center of
            // the map
            // to the current center of the control.
            goCenterUI.addEventListener('click', () => {
              let currentCenter = control.getCenter();
              map.setCenter(currentCenter);

              marker.setAnimation(google.maps.Animation.BOUNCE); // make the marker BOUNCE when {my location} button is pressed.
              setTimeout(()=> marker.setAnimation(null), 1500); // stop bouncing after 1.5seconds.
            });

            marker.addListener('drag', function(){ // while dragging the marker a popup notify the user dropping will change location.
                infoWindow.setContent('Drop to set a new location');
                infoWindow.open(map,marker);
                console.log('dragging..');
            });

            // change the location based on where the user drag & dropped the marker.
            marker.addListener('dragend', () => {
                infoWindow.close();
                let newCenter = map.getCenter();
                control.setCenter(marker.position); // set the location to the marker's position.
            });

            // marker BOUNCE when clicked then stop after 1.5seconds.
            marker.addListener('click', ()=>{
              if (marker.getAnimation() !== null){
                marker.setAnimation(null);
              } else{
                marker.setAnimation(google.maps.Animation.BOUNCE);
                setTimeout(()=> marker.setAnimation(null), 1500);
              }
              // open a popup to notify the user changing location is by dragging the marker.
              infoWindow.setContent('Drag to change your location');
              infoWindow.open(map,marker);
              setTimeout(()=>infoWindow.close(), 1100);
            });

          let requestPlacesDetails = {
            placeId : 'ChIJN1t_tDeuEmsRUsoyG83frY4'
          }

          let PlacesDetails = (results, status) =>{
            if(status == google.maps.places.PlacesServiceStatus.OK){
              for(let i = 0; i < results.length; i++){
                console.log(results[i]);
              }
            }

          }

          let service = new google.maps.places.PlacesService(map);

          service.getDetails(requestPlacesDetails, PlacesDetails); // get details about every place nearby the user location.

            /**
            * Define a property to hold the center state.
            * @private
            */
            CenterControl.prototype.center_ = null;

            /**
            * Gets the map center.
            * @return {?google.maps.LatLng}
            */
            CenterControl.prototype.getCenter = function() {
              return this.center_;
            };

            /**
            * Sets the map center.
            * @param {?google.maps.LatLng} center
            */
            CenterControl.prototype.setCenter = function(center) {
              this.center_ = center;
            };

          }
        }, function() {
          handleLocationError(true, infoWindow, map.getCenter());
        });
      } else {
        // Browser doesn't support Geolocation
        handleLocationError(false, infoWindow, map.getCenter());
      }
    }


    function handleLocationError(browserHasGeolocation, infoWindow, pos) {
      infoWindow.setPosition(pos);
      infoWindow.setContent(browserHasGeolocation ?
                            'Error: The Geolocation service failed.' :
                            'Error: Your browser doesn\'t support geolocation.');
      infoWindow.open(map);
    }


</script>
</html>

我的node代码: -

var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');

var index = require('./routes/index');
var users = require('./routes/users');

var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'hbs');

// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

app.use('/', index);
app.use('/users', users);


app.listen(4000, ()=>{
  console.log('server is up on 3000');
})
// catch 404 and forward to error handler
app.use(function(req, res, next) {
  var err = new Error('Not Found');
  err.status = 404;
  next(err);
});

// error handler
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render('error');
});

module.exports = app;

**编辑3 **控制台错误: - enter image description here

1 个答案:

答案 0 :(得分:1)

改变这个:

<script src=".././public/javascripts/main.js"></script>

到此:

<script src="/javascripts/main.js"></script>

您在资源网页中使用的路径需要相对于public目录,而不是相对于网页目录,并且应该以{{1​​}}开头。

这行代码:

/

告诉您的快速服务器查看app.use(express.static(path.join(__dirname, 'public'))); 子目录中是否匹配请求的路径。因此,当浏览器请求public时,它会查找文件所在的/javascripts/main.js。这里的关键是您在网页中使用的网址需要假设根目录是public/javascripts/main.js中的目录,在您的情况下为express.static()。因此,请求的任何网址都会附加到public路径,并且应该以{{1​​}}开头。

另一个例子是,如果浏览器请求public,那么您的/命令将查找/test.js。要查找express.static(),您需要将public/test.js放入网页,以便浏览器提出要求。