我有一个很简单的JS使用navigator。geolocation。getcurrentposition jammy。

$(document).ready(function(){
  $("#business-locate, #people-locate").click(function() {
    navigator.geolocation.getCurrentPosition(foundLocation, noLocation);
  });

  navigator.geolocation.getCurrentPosition(foundLocation, noLocation);

  function foundLocation(position) {
    var lat = position.coords.latitude;
    var lon = position.coords.longitude;
    var userLocation = lat + ', ' + lon;
    $("#business-current-location, #people-current-location").remove();
    $("#Near-Me")
      .watermark("Current Location")
      .after("<input type='hidden' name='business-current-location' id='business-current-location' value='"+userLocation+"' />");
    $("#people-Near-Me")
      .watermark("Current Location")
      .after("<input type='hidden' name='people-current-location' id='people-current-location' value='"+userLocation+"' />");
  }
  function noLocation() {
    $("#Near-Me").watermark("Could not find location");
    $("#people-Near-Me").watermark("Could not find location");
  }
})//end DocReady

基本上,这里发生的事情是我们得到当前位置,如果它得到了,两个“水印”被放置在两个字段中,表示“当前位置”,两个隐藏字段被创建,并使用latong数据作为它们的值(它们在开始时被删除,这样它们就不会每次都重复)。还有两个按钮,它们有一个点击功能,做同样的事情。 不幸的是,每隔三次左右,它就会奏效。 这里有什么问题?


当前回答

截至2020年年中,这里的答案都没有提供任何解释,只是黑客攻击或猜测。

正如@Coderer在我之前指出的,安全上下文(https)是今天需要的,所以在越来越多的设备上,地理定位在普通http下根本不起作用:

安全上下文 此特性仅在安全上下文中(HTTPS)以及部分或所有支持的浏览器中可用。

getCurrentPosition()(和watchPosition()更适合这里)的第三个参数是PositionOptions对象,由以下属性组成:

enableHighAccurancy (default false): if set to true, response is slower and more accurate. If you got timeout errors, keep this to false. If the accurancy is low, set it to true. In my tests the accurancy varies and on some devices it has no effect. On other devices setting true may cause surprisingly quick battery depletion. timeout (default infinity): milliseconds before the API gives up and calls the error handler (the second parameter). Today most mobile devices with geolocation enabled and permission granted for the browser/page get the value with reasonable accurancy within a second. When the geolocation service is not available, alternative method like geo IP may be used, the delay can be many seconds and the precision usually ranges from questionable to useless. maximumAge (default 0): milliseconds when cached value is valid, the device may decide to use valid cached data instead of sensor measure. I usually set this to non-zero values with slowly moving devices (like walking with mobile phone). On static devices, Infinity can be set to avoid consequent reading errors.

正如@YoLoCo在我之前指出的那样,getCurrentPosition()和watchPosition()会干扰,我在2020年确认了他的结果。通常,使用watchPosition代替getCurrentPosition周期性调用。

其他回答

我有一个部分的答案,但可惜不是一个完整的答案。

首先,要意识到getCurrentPosition的默认超时是无限的(!)。这意味着如果getCurrentPosition挂在后端某个位置,则永远不会调用错误处理程序。

为了确保你得到一个超时,添加可选的第三个参数到你对getCurrentPosition的调用,例如,如果你想让用户等待不超过10秒,然后给他们一个线索发生了什么,使用:

navigator.geolocation.getCurrentPosition(successCallback,errorCallback,{timeout:10000});

其次,我在不同的环境中经历了非常不同的可靠性。在家里,我在一两秒钟内就会收到回复,尽管准确率很低。

然而,在工作中,我经历了相当奇怪的行为变化:地理定位在一些电脑上一直有效(当然IE除外),另一些只能在chrome和safari上工作,但不能在firefox上工作(壁虎问题?),另一些只工作了一次,然后就失败了——这种模式每小时都在变化,每天都在变化。有时你有一台“幸运”的电脑,有时没有。也许满月时宰山羊会有帮助?

我还不能理解这一点,但我怀疑后端基础设施比各种推动这一功能的书籍和网站上宣传的更不平衡。如果您希望错误处理程序正常工作,我真的希望他们能更直接地说明这个特性是多么不可靠,以及超时设置是多么重要。

今天我一直在试着教学生这些东西,遇到了一个尴尬的情况,我自己的电脑(在投影仪和几个大屏幕上)无声地失败了,而大约80%的学生几乎立即得到了结果(使用完全相同的无线网络)。当我的学生也犯拼写错误和其他错误时,当我自己的电脑也出现故障时,解决这些问题是非常困难的。

在我们的例子中,它总是第一次工作,但重新运行函数3-4次以上,它就失败了。

简单的解决方法:将其值存储在LocalStorage中。

之前:

navigator.geolocation.getCurrentPosition((position) => {
  let val = results[0].address_components[2].long_name;
  doSthWithVal(val);      
}, (error) => { });

后:

if(localStorage.getItem('getCurrentPosition') !== null) {
  doSthWithVal(localStorage.getItem('getCurrentPosition'));
}
else {
  navigator.geolocation.getCurrentPosition((position) => {
      let val = results[0].address_components[2].long_name;
      localStorage.setItem('getCurrentPosition',val);
      doSthWithVal(val);      
  }, (error) => { });
}

我一直有类似的问题,并一直在研究浏览器对getCurrentPosition的调用频率有限制的可能性。似乎我可以经常得到一个位置,但如果我刷新页面马上就会超时。如果我等一会儿,我通常可以再次得到一个位置。这通常发生在FF上。在Chrome和Safari中,我还没有注意到getCurrentPosition超时。只是一个想法……

虽然我找不到任何文档来支持这一点,但这是我经过多次测试后得出的结论。也许其他人有这方面的信息?

我发现,这种方法行不通

navigator.geolocation.getCurrentPosition(function() {...}, function(err) {...}, {});

But

这种方法非常有效

function storeCoordinates(position) {
    console.log(position.coords.latitude, position.coords.longitude);
}    

function errorHandler() {...}

navigator.geolocation.getCurrentPosition(storeCoordinates, errorHandler, { enableHighAccuracy: true, timeout: 20000, maximumAge: 0 });

以下是我的解决方案,感谢一个闭包:

  function geoloc(success, fail){
    var is_echo = false;
    if(navigator && navigator.geolocation) {
      navigator.geolocation.getCurrentPosition(
        function(pos) {
          if (is_echo){ return; }
          is_echo = true;
          success(pos.coords.latitude,pos.coords.longitude);
        }, 
        function() {
          if (is_echo){ return; }
          is_echo = true;
          fail();
        }
      );
    } else {
      fail();
    }
  }

  function success(lat, lng){
    alert(lat + " , " + lng);
  }
  function fail(){
    alert("failed");
  }

  geoloc(success, fail);