9 Stimmen

Geolocation-Feedback bei der Annahme der Anfrage

Die Geolocation-Implementierung ist recht gut und es gibt nur wenige Schritte zu beachten, aber eine Sache fehlt, denke ich. Im nicht in der Lage zu sehen, wenn der Benutzer die Anforderung akzeptiert oder nicht (bevor ich das Positionsobjekt erhalten), ich weiß nicht, wenn der Benutzer nur meine Anforderung (während meiner Timeout) ignoriert oder wenn die Anforderung nur verloren gehen (und der Ausfall-Callback doesnt für keinen Grund aufgerufen).

Es wäre nützlich, einen Zeitstempel zu setzen, wenn der Benutzer die Anfrage annimmt, ich konnte nichts finden, das mir diese Art von Antwort gibt.

6voto

scunliffe Punkte 60080

Sie ist Teil des Geolocation API :

// navigator.geolocation.getCurrentPosition(successCallback, errorCallback, options);
navigator.geolocation.getCurrentPosition(
  function(position){
    //do something with position;
  }, function(){
    //handle condition where position is not available
    //more specifically you can check the error code...
    //error.code == 1
    if(error.PERMISSION_DENIED){
      alert("you denied me! ");
    }
});

Wenn Sie den errorCallback... angeben, können Sie verfolgen, ob der Benutzer den Zugang verweigert hat.

Möglicherweise Fehlercodes umfassen:

error.PERMISSION_DENIED    (numeric value 1)
error.POSITION_UNAVAILABLE (numeric value 2)
error.TIMEOUT              (numeric value 3)

6voto

scunliffe Punkte 60080

Nach meinem neuen Verständnis dessen, was Sie wollen, wollen Sie so etwas wie das hier. (Getestet: in Opera - funktioniert, Firefox 3.6 & Chrome 8 - nicht so sehr (ich brauche mehr Zeit zum Debuggen))

Szenario: Die Seite versucht, den Standort abzufragen... aber der Benutzer ignoriert die Eingabeaufforderung vollständig, so dass es kein (Annehmen oder Ablehnen) gibt, und da die Anfrage nach dem Standort nie gesendet wird, gibt es auch kein Timeout!

Auf dieser Grundlage können Sie Ihre eigene Logik hinzufügen, um dieses Szenario zu behandeln. Für dieses Beispiel werde ich meine eigene "Wrapper"-Methode prototypisieren. (für die pingelig - ich bin nicht duldet mit Globals etc. Ich habe nur versucht, etwas zum Laufen zu bringen)

navigator.geolocation.requestCurrentPosition = function(successCB, errorCB, timeoutCB, timeoutThreshold, options){
  var successHandler = successCB;
  var errorHandler = errorCB;
  window.geolocationTimeoutHandler = function(){
    timeoutCB();
  }
  if(typeof(geolocationRequestTimeoutHandler) != 'undefined'){
    clearTimeout(window['geolocationRequestTimeoutHandler']);//clear any previous timers
  }
  var timeout = timeoutThreshold || 30000;//30 seconds
  window['geolocationRequestTimeoutHandler'] = setTimeout('geolocationTimeoutHandler()', timeout);//set timeout handler
  navigator.geolocation.getCurrentPosition(
    function(position){
      clearTimeout(window['geolocationRequestTimeoutHandler']);
      successHandler(position);
    },
    function(error){
      clearTimeout(window['geolocationRequestTimeoutHandler']);
      errorHandler(error);
    },
     options
  );
};
function timeoutCallback(){
  alert('Hi there! we are trying to locate you but you have not answered the security question yet.\n\nPlease choose "Share My Location" to enable us to find you.');
}
function successCallback(position){
  var msg = '';
  msg += 'Success! you are at: ';
  msg += '\nLatitude: ' + position.coords.latitude;
  msg += '\nLongitude: ' + position.coords.longitude;
  msg += '\nAltitude: ' + position.coords.altitude;
  msg += '\nAccuracy: ' + position.coords.accuracy;
  msg += '\nHeading: ' + position.coords.heading;
  msg += '\nSpeed: ' + position.coords.speed;
  alert(msg);
}
function errorCallback(error){
  if(error.PERMISSION_DENIED){
    alert("User denied access!");
  } else if(error.POSITION_UNAVAILABLE){
    alert("You must be hiding in Area 51!");
  } else if(error.TIMEOUT){
    alert("hmmm we timed out trying to find where you are hiding!");
  }
}
navigator.geolocation.requestCurrentPosition(successCallback, errorCallback, timeoutCallback, 7000, {maximumAge:10000, timeout:0});

Das Konzept besteht darin, zunächst einen Timer einzurichten (standardmäßig 30 Sekunden, falls nicht eingestellt). Wenn der Benutzer nichts unternimmt, bevor der Timer abläuft, wird ein TimeoutCallback aufgerufen.

Anmerkungen:

  1. Einige Benutzeroberflächen (z.B. iPhone/iPad/iPod Safari) können die Eingabeaufforderung zum Zulassen/Ablehnen modal machen - so kann der Benutzer nicht wirklich fortfahren, bis er etwas ausgewählt hat (ich würde vorschlagen, diese Benutzer in Ruhe zu lassen und die Standard-Benutzeroberfläche die Dinge erledigen zu lassen
  2. Wenn der Benutzer die Anfrage (spät) zulässt, kann die Zeitüberschreitung immer noch ausgelöst werden, bevor die Antwort zurückkommt - ich glaube nicht, dass Sie etwas dagegen tun können
  3. Der obige Code ist nur ein Beispiel... er muss bereinigt werden.

5voto

Maertz Punkte 4847

Getestet wurde es erfolgreich in FF 3.5, Opera 10.6, Chrome8, IE6-8.

var succeed = function(obj) {
    navigator.geolocation.received = true;
    !navigator.geolocation.timedout?alert('GOT YAH'):alert('GOT YAH but user was to slow'); 
};
var failed  = function(obj) { 
    navigator.geolocation.received = true;
    !navigator.geolocation.timedout?alert('just failed'):alert('failed and user was to slow as well, tzz ._.'); 
};
var timedout    = function() {
    navigator.geolocation.timedout = true; // could be used for other callbacks to trace if its timed out or not
    !navigator.geolocation.received?alert('Request timed out'):null;    
}

// Extend geolocation object
if ( navigator.geolocation  ) {
    navigator.geolocation.retrievePermission = function retrievePermission(succeed,failed,options,timeout) {
        this.received = false;              // reference for timeout callback
        this.timedout = false;              // reference for other callbacks
        this.getCurrentPosition.apply(this,arguments);  // actual request

        // Trigger timeout with its function; default timeout offset 5000ms
        if ( timeout ) {
            setTimeout(timeout.callback,timeout.offset || 5000);
        }
    }

    // New location request with timeout callback
    navigator.geolocation.retrievePermission(succeed,failed,{},{
        offset: 10000, // miliseconds
        callback: timedout  
    });

// Awesome thingy is not implemented
} else {
    alert('geolocation is not supported');
}

Mit diesem Workaround wissen wir, ob die Anfrage eine Zeitüberschreitung hatte, auch wenn der Erfolgs/Fehlschlag-Callback danach aufgerufen wird.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X