我有一个很简单的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数据作为它们的值(它们在开始时被删除,这样它们就不会每次都重复)。还有两个按钮,它们有一个点击功能,做同样的事情。 不幸的是,每隔三次左右,它就会奏效。 这里有什么问题?


当前回答

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

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

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

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

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

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

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

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

其他回答

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

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

我也遇到了同样的情况。我尝试了超时解决方案,但不可靠。我发现如果你只调用它两次,位置就会正确刷新

function getLocation(callback)
{   
    if(navigator.geolocation)
    {
        navigator.geolocation.getCurrentPosition(function(position)
        {
            navigator.geolocation.getCurrentPosition(callback, function(){},{maximumAge:0, timeout:10000});
        },function(){}, {maximumAge:0, timeout:10000});
    }
    return true;
}

这当然是有点慢,但我没有给我错误的位置一次。我有它击中超时几次,没有返回任何东西,但除此之外,它工作得很好。我知道这仍然有点老套,我期待有人找到真正的解决方案。

或者,如果你想确保它会一直尝试,直到你想放弃,你可以试试这样的方法。

//example
$(document).ready(function(){
    getLocation(function(position){
        //do something cool with position
        console.log(position);
    });
});


var GPSTimeout = 10; //init global var NOTE: I noticed that 10 gives me the quickest result but play around with this number to your own liking


//function to be called where you want the location with the callback(position)
function getLocation(callback)
{   
    if(navigator.geolocation)
    {
        var clickedTime = (new Date()).getTime(); //get the current time
        GPSTimeout = 10; //reset the timeout just in case you call it more then once
        ensurePosition(callback, clickedTime); //call recursive function to get position
    }
    return true;
}

//recursive position function
function ensurePosition(callback, timestamp)
{
    if(GPSTimeout < 6000)//set at what point you want to just give up
    {
        //call the geolocation function
        navigator.geolocation.getCurrentPosition(
            function(position) //on success
        {
                //if the timestamp that is returned minus the time that was set when called is greater then 0 the position is up to date
            if(position.timestamp - timestamp >= 0)
                {
                    GPSTimeout = 10; //reset timeout just in case
                    callback(position); //call the callback function you created
                }
                else //the gps that was returned is not current and needs to be refreshed
                {
                    GPSTimeout += GPSTimeout; //increase the timeout by itself n*2
                    ensurePosition(callback, timestamp); //call itself to refresh
                }
            },
            function() //error: gps failed so we will try again
            {
                GPSTimeout += GPSTimeout; //increase the timeout by itself n*2
                ensurePosition(callback, timestamp);//call itself to try again
            },
            {maximumAge:0, timeout:GPSTimeout}
        )
    }       
}

我可能在这里有一些打字和拼写错误,但我希望你能明白。如果有人有问题或者找到更好的建议,请告诉我。

这是我解决这个问题的hack方法,至少它在所有当前的浏览器中都有效(在Windows上,我没有Mac):

if (navigator.geolocation) {
    var location_timeout = setTimeout("geolocFail()", 10000);

    navigator.geolocation.getCurrentPosition(function(position) {
        clearTimeout(location_timeout);

        var lat = position.coords.latitude;
        var lng = position.coords.longitude;

        geocodeLatLng(lat, lng);
    }, function(error) {
        clearTimeout(location_timeout);
        geolocFail();
    });
} else {
    // Fallback for no geolocation
    geolocFail();
}

如果有人点击“关闭”或选择“不”或在Firefox上选择“永不共享”选项,这也会起作用。

很笨拙,但很有效。

对于开发iPhone应用程序的人来说……

如果你的代码在ios9 +的UIWebView中运行,那么你必须在应用的plist中设置NSLocationWhenInUseUsageDescription。

如果你不设置它,那么getCurrentPosition将永远不会回调,用户也永远不会被提示。

我最近自己也注意到了这个问题,我不确定它是怎么来的,但它有时会出现firefox在缓存中加载的东西上卡住。在清除缓存并重新启动firefox后,它似乎再次发挥作用。