navigator.geolocation.getCurrentPosition sometimes works sometimes doesn't

前端 未结 25 1682
伪装坚强ぢ
伪装坚强ぢ 2020-11-22 13:33

So I have a pretty simple bit of JS using the navigator.geolocation.getCurrentPosition jammy.

$(document).ready(function(){
  $(\"#business-locate, #people-l         


        
相关标签:
25条回答
  • 2020-11-22 14:13

    It might be a good idea to use an IP address geo location service as a fallback method when getCurrentPosition fails. For example with our api https://ip-api.io

    $.getJSON("http://ip-api.io/json/",
        function(result) {
            console.log(result);
        });
    
    0 讨论(0)
  • 2020-11-22 14:14

    here is my solution thanks to a closure :

      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);
    
    0 讨论(0)
  • 2020-11-22 14:15

    I'm still getting spotty results in 2017, and I have a theory: the API documentation says that the call is now only available "in a secure context", i.e. over HTTPS. I'm having trouble getting a result in my development environment (http on localhost) and I believe this is why.

    0 讨论(0)
  • 2020-11-22 14:18

    This is the hacky way that I am getting around this, at least it works in all current browsers (on Windows, I don't own a 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();
    }
    

    This will also work if someone clicks the close or chooses no or chooses the Never Share option on Firefox.

    Clunky, but it works.

    0 讨论(0)
  • 2020-11-22 14:18

    So I was running into the same thing. I tried the timeout solution which worked but not reliably. I found that if you just call it twice the location is refreshed properly

    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;
    }
    

    this of course is a little slower but I have not had it give me the wrong position once. I have had it hit the timeout a few times and not return anything but other then that it works great. I know this is still a little hacky and I am looking forward to someone finding the real solution.

    Or if you want to make sure it is going to keep trying until you want to give up you could try something like this.

    //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}
            )
        }       
    }
    

    I probably have some typeos and some spelling errors in here but I hope you get the idea. Let me know if anyone has questions or if someone finds something better.

    0 讨论(0)
  • 2020-11-22 14:18

    This happened to me when using Firefox's responsive design mode. There has been a bug report filed. For now, just don't use responsive design mode while using the Geolocation API.

    0 讨论(0)
提交回复
热议问题