javascript - 地理位置/Javascript 范围问题

标签 javascript google-maps geolocation

我有一个关于地理定位和 javascript 变量范围的问题。 我一直在玩弄它,但我是一个 php 人,js 不是我最好的语言。我正在制作谷歌地图,我想将用户坐标设置为 map 中心并设置缩放比例。如果请求失败/被拒绝,那么我将使用 Web 服务从 IP 获取它们的近似坐标。我想从 getLocation() 函数中获取位置/缩放,但我无法从 navigator.geolocation.getCurrentPosition() 中获取信息

我已经尝试从错误和位置函数中返回对象,但看起来它没有为此设置,除了错误代码我什么也得不到。我以为我可以设置 var 然后覆盖它,但我不能让它返回任何东西,但未定义,我仍然没有 100% 理解范围和提升足以找到解决方案。

geolocFail() 按预期工作,正确返回对象。由于它是从 navigator.geolocation.getCurrentPosition 中的错误函数调用的 - 我无法从那里获取信息。

      function getLocation() {

       var mapLocation;

        if (navigator.geolocation) {
              var location_timeout = setTimeout("geolocFail()", 10000);
              navigator.geolocation.getCurrentPosition(
                function(position) {
                    clearTimeout(location_timeout);
                    mapLocation = {position: position.coords.latitude + "," + position.coords.longitude,  zoom:10};
                }, function(error) {
                    clearTimeout(location_timeout);
                        switch(error.code) {
                            case error.PERMISSION_DENIED:
                                alertDiv.innerHTML="<p class='text-danger'>User denied the request for Geolocation.</p>";
                                break;
                            case error.POSITION_UNAVAILABLE:
                                alertDiv.innerHTML="<p class='text-danger'>User Location information is unavailable.</p>";
                                break;
                            case error.TIMEOUT:
                                alertDiv.innerHTML="<p class='text-danger'>The request to get user location timed out.</p>";
                                break;
                            case error.UNKNOWN_ERROR:
                                alertDiv.innerHTML="<p class='text-danger'>An unknown error occurred.</p>";
                                break;
                        }
                    mapLocation =  geolocFail(); 
                });
        } 
        else {
            // Fallback for no geolocation
            alertDiv.innerHTML="<p class='text-danger'>Geolocation is not supported by this browser.</p>";
                    mapLocation =  geolocFail();
        }

      }



  function geolocFail(){
        //fallback to webservice
        var xmlhttp;
        if (window.XMLHttpRequest) {
            // code for IE7+, Firefox, Chrome, Opera, Safari
            xmlhttp = new XMLHttpRequest();
        } else {
            // code for IE6, IE5
            xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
        }
        xmlhttp.onreadystatechange = function(){
          if (xmlhttp.readyState==4 && xmlhttp.status==200){
              if (typeof callback == "function") {
                      // apply() sets the meaning of "this" in the callback
                      callback.apply(xmlhttp);
                    }
          }
        }
        xmlhttp.open("GET","/map/determineLocation?t=" + Math.random(),true);
        xmlhttp.send(); 
        if(this.responseText){
           var mapLocation = {position: this.responseText,  zoom:10}
        }
        else{
          var mapLocation = {position: "40.0000,-100.0000",  zoom:4};
        }
        return mapLocation;
      }

最佳答案

您的具体问题

您的回调是异步的。虽然它们是在一个地方定义的,但您不知道它们何时会被远程服务实际触发。

最好的办法是将您的响应代码包装在一个函数中,然后您在回调中调用该函数来处理响应并对其进行设计,使其不依赖于任何类型的程序流。

使用一个函数在位置数据返回时获取和响应它,而不是尝试将其分配给一个变量,然后尝试在调用 navigator.geolocation.getCurrentPosition 后立即使用该变量.

此(简化的)代码有效:

function respond_to_received_data(position) {
  console.log(position);
}
function respond_to_error_data(error) {
  console.log(error);
} 

mapLocation = navigator.geolocation.getCurrentPosition(
  function(position) {
    respond_to_received_data(position);
  },
  function(error) {
    respond_to_received_data(error);
  }
);

fiddle here

请参阅following community wiki resource有关异步性的更多信息:

但是,仅供引用有关范围和提升:

JavaScript 范围

JavaScript 有两个作用域,全局作用域和函数作用域。在函数外部声明的任何变量(使用 var 关键字)都具有全局范围,即它可以在您网页中的任何位置使用。在一个函数内声明的任何变量(同样,使用 var 关键字)将只对该函数可用,并且为了在该函数之外使用必须直接返回,或者作为返回函数表达式的一部分返回。

这解释了 Javascript 中非常常见的将代码包装在立即调用且可扩展的匿名函数中的模式:

(function() { /* code in controlled scope */ }());

Todd Motto will help you learn more .

在 Javascript 中提升

在任何给定的范围内,javascript 首先收集范围内使用的变量并首先定义它们,或者用一个值,或者如果此时不能用未定义的值推导出一个变量。有关吊装的更多信息,请参阅 Mozilla Dev Network description .

帮助形象化上述内容的示例

这两种行为的组合可以用范围中间的 for 循环来说明。来自 for 循环的 increment 变量在作用域开始时将作为未定义的进行访问,并且在作用域结束时仍然可用,设置为它在循环执行期间的最后一个值。

// globally defined
var glob = 'hi';
(function() {
  var j = 4;
  console.log(j); // => 4
  console.log(glob); // => 'hi'
  console.log(inLoop); // => undefined

  // NB if this was set to anything not used in the scope then execution would be halted by an 'undefined' error in the code
  console.log(i); // => undefined
  for (var i = 0; i < 10; i ++) 
  { 
    var inLoop = 'xyz';
  }

  console.log(i); // => 10
  console.log(inLoop); // => 10
}());
console.log(glob); // => 'hi'

fiddle here

PS new version of JS has the let keyword为所谓的“ block 作用域”或类似 PHP 定义了一个变量 :-)

关于javascript - 地理位置/Javascript 范围问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28592859/

相关文章:

ios - 从 NIB 加载/创建 GeoLocation View - IOS 和 MapKit

javascript - Angularjs复选框过滤器,如何做重置按钮?

javascript - 如何在单个产品页面 woocommerce 上显示高级自定义字段 Google map

java - 安卓 |获取当前位置的北/东南/东/西经纬度和经度范围

javascript - 谷歌地图 - 无法将文本和图像插入信息窗口

java - 使用 Google Maps Api V2 时,Android 2.2 或 4.1.2 模拟器上缺少 Google Play 服务

java - 如何在后台接收位置更新? (API 26)

java - 以下划线开头但不包含任何下划线的正则表达式

javascript - js 以微小速度进行对 Angular 线运动

javascript - JQM 向可折叠标题添加按钮