3

重複の可能性:
JavaScript変数スコープ

スクリプトに問題があります。pos関数からlat、lngの値を取得したいのですが、コンソールで要素を検査すると、次のエラーが発生します。

「UncaughtReferenceError:lat is not defined TEST.html:30(無名関数)」

30行目は次のとおりです。varlatlng=new google.maps.LatLng(lat、lng); これは私の完全なコードです:

<script type="text/javascript">

navigator.geolocation.getCurrentPosition (function (pos){
  lat = pos.coords.latitude;
  lng = pos.coords.longitude;
});

  var directionsDisplay;
  var directionsService = new google.maps.DirectionsService();
  var map;
  var latlng = new google.maps.LatLng (lat, lng);
  var oceanBeach = new google.maps.LatLng(-6.2501199999999999,106.75937);

  function initialize() {
    directionsDisplay = new google.maps.DirectionsRenderer();
    var mapOptions = {
      zoom: 14,
      mapTypeId: google.maps.MapTypeId.ROADMAP,
      center: latlng
    }
    map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
    directionsDisplay.setMap(map);
  }

  function calcRoute() {
    var selectedMode = document.getElementById("mode").value;
    var request = {
        origin: latlng,
        destination: oceanBeach,
        // Note that Javascript allows us to access the constant
        // using square brackets and a string value as its
        // "property."
        travelMode: google.maps.TravelMode[selectedMode]
    };
    directionsService.route(request, function(response, status) {
      if (status == google.maps.DirectionsStatus.OK) {
        directionsDisplay.setDirections(response);
      }
    });
  }
</script>
4

2 に答える 2

0

少なくとも2つの問題があります。

  1. 変数のスコープ(変数はサブ関数で定義されており、使用しようとしているスコープでは使用できません)

  2. getCurrentPosition()関数は非同期です。つまり、呼び出してからしばらくすると終了し、完了コールバック関数を呼び出したときにのみ完了します。したがって、関数呼び出し後に結果を使用しようとした時点では、まだ終了していません。

非同期であることを処理getCurrentPosition()するには、次のようにする必要があります。

navigator.geolocation.getCurrentPosition (function (pos){
    var lat = pos.coords.latitude;
    var lng = pos.coords.longitude;
    var latlng = new google.maps.LatLng (lat, lng);
    var oceanBeach = new google.maps.LatLng(37.7683909618184, -122.51089453697205);      
    // any further code that uses these variables
});

// no code here that uses the results of getCurrentPosition() 
// because it has not completed yet

あなたはここで同様の質問と答えを見ることができます:navigator.geolocationの非同期の性質に対処することができません

于 2013-01-29T23:53:13.363 に答える
0

次のように書くと問題になるでしょうか。

navigator.geolocation.getCurrentPosition (function (pos){
     var lat = pos.coords.latitude;
     var lng = pos.coords.longitude;
     var latlng = new google.maps.LatLng (lat, lng);
     var oceanBeach = new google.maps.LatLng(37.7683909618184, -122.51089453697205);
});

それが叫ぶ理由は、コールバック関数の外部で定義されている latlng および oceanBeach とは異なるスコープで lat が定義されており、そこにアクセスできないためです。

アップデート

状況を考慮して、コールバックを使用して問題を解決できます。つまり、 getCurrentPosition を次のような独自の関数にするなどのことを行います。

 function getCurrentLocation(callback) {
   if(navigator.geolocation) {
     navigator.geolocation.getCurrentPosition(function(pos) {
     var lat = pos.coords.latitude;
     var lng = pos.coords.longitude;
     callback(new google.maps.LatLng(lat,lng), new google.maps.LatLng(-6.2501199999999999,106.75937));
   });
  }
  else {
   throw new Error("Your browser does not support geolocation.");     
  }
} 

そして、それぞれに対して個別のコールバックでそれらを呼び出します。

   getCurrentLocation(function(latlng,oceanBeach){
  // work with latlng and ocean beach here
  });

そして今、最終的に各関数から関数を呼び出します

<script type="text/javascript">

var directionsDisplay;
var directionsService = new google.maps.DirectionsService();

function initialize() {
 getCurrentLocation(function(latlng,oceanBeach){
   directionsDisplay = new google.maps.DirectionsRenderer();
   var mapOptions = {
   zoom: 14,
   mapTypeId: google.maps.MapTypeId.ROADMAP,
   center: latlng
   }
   map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
   directionsDisplay.setMap(map);
 });

}

</script>

calcRoute にも同じ手法を使用します。注 :directionDisplay とdirectionService をグローバルに保持する代わりに、この全体をクラスにして、よりクリーンでよりオブジェクト指向にする必要があります。

于 2013-01-29T23:55:03.753 に答える