245 votes

navigator.geolocation.getCurrentPosition parfois fonctionne parfois non

J'ai donc un petit bout de JS assez simple qui utilise le jammy navigator.geolocation.getCurrentPosition.

$(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

En gros, ce qui se passe ici est que nous obtenons la position actuelle, si elle est obtenue, deux "filigranes" sont placés dans deux champs qui disent "Position actuelle" et deux champs cachés sont créés avec les données de longueur de la latte comme valeur (ils sont supprimés au début pour qu'ils ne soient pas dupliqués à chaque fois). Il y a aussi deux boutons qui ont une fonction de clic liée à eux et qui font la même chose. Malheureusement, cela fonctionne environ une fois sur trois. Quel est le problème ?

0 votes

Définissez peut-être les fonctions avant de les utiliser.

4 votes

@digitalFresh, cela ne devrait pas avoir d'importance car l'analyseur JS recherche ces déclarations avant que le code ne commence à être exécuté.

0 votes

Est-il possible que l'utilisation de jQuery soit à l'origine de problèmes ?

380voto

brennanyoung Points 1846

J'ai eu exactement Je rencontre le même problème et je ne trouve pratiquement aucune information en ligne à ce sujet. Rien du tout dans les livres. Finalement, j'ai trouvé cette requête sobre sur stackoverflow et (ha !) c'était l'impulsion finale dont j'avais besoin pour créer un compte ici.

Et j'ai une réponse partielle, mais hélas pas complète.

Tout d'abord, sachez que le délai d'attente par défaut pour getCurrentPosition est infini ( !). Cela signifie que votre gestionnaire d'erreurs ne jamais être appelé si getCurrentPosition se bloque quelque part dans le back-end.

Pour vous assurer d'obtenir un délai d'attente, ajoutez le troisième paramètre facultatif à votre appel à getCurrentPosition. Par exemple, si vous souhaitez que l'utilisateur n'attende pas plus de 10 secondes avant de lui donner un indice sur ce qui se passe, utilisez :

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

Deuxièmement, j'ai fait l'expérience d'une fiabilité très différente dans des contextes différents. Ici, à la maison, j'obtiens un rappel en une ou deux secondes, mais la précision est médiocre.

Au travail, cependant, j'expérimente des variations de comportement assez bizarres : La géolocalisation fonctionne sur certains ordinateurs en permanence (à l'exception d'IE, bien sûr), d'autres ne fonctionnent que dans chrome et safari mais pas dans firefox (problème de gecko ?), d'autres encore fonctionnent une fois, puis échouent par la suite - et le schéma change d'heure en heure, de jour en jour. Parfois vous avez un ordinateur "chanceux", parfois non. Peut-être que l'abattage des chèvres à la pleine lune pourrait aider ?

Je n'ai pas été en mesure de le comprendre, mais je soupçonne que l'infrastructure dorsale est plus inégale qu'annoncée dans les divers livres et sites Web qui font la promotion de cette fonction. J'aimerais vraiment qu'ils soient un peu plus directs sur le fait que cette fonctionnalité est bancale, et l'importance de ce paramètre de timeout, si vous voulez que votre gestionnaire d'erreur fonctionne correctement. .

J'ai essayé d'enseigner ce genre de choses à des étudiants aujourd'hui, et je me suis retrouvé dans la situation embarrassante où mon propre ordinateur (sur le projecteur et plusieurs grands écrans) tombait en panne silencieusement, alors qu'environ 80 % des étudiants obtenaient un résultat presque instantanément (en utilisant exactement le même réseau sans fil). Il est très difficile de résoudre ces problèmes lorsque mes étudiants font également des fautes de frappe et d'autres gaffes, et lorsque mon propre ordinateur est également en panne.

En tout cas, j'espère que cela aidera certains d'entre vous. Merci pour la vérification de la santé mentale !

7 votes

Bonne information détaillée, merci ! Je rencontre les mêmes problèmes, mais uniquement sur Firefox 3.6.13. Chrome semble être assez fiable.

0 votes

Même chose ici, et le paramètre maximumAge ne semble pas être fiable non plus. Merci pour le post.

1 votes

Joli coup, j'ai eu le même problème (sur une Samsung Galaxy Tab, 10.1, fonctionnant sous Android 4.0.3 ), une fois que j'ai utilisé le paramètre timeout ci-dessus, j'ai pu résoudre le problème.

72voto

xiaohouzi79 Points 3165

C'est la méthode que j'utilise pour contourner ce problème, mais elle fonctionne dans tous les navigateurs actuels (sous Windows, je ne possède pas de 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();
}

Cela fonctionnera également si quelqu'un clique sur la fermeture ou choisit non ou choisit l'option Ne jamais partager sur Firefox.

Maladroit, mais ça marche.

1 votes

+1 Mais vous manquez le geolocFail(); et le gestionnaire d'erreurs getcodeLatLng(); géocodeur.

0 votes

Super - le minuteur fonctionne parfaitement si quelqu'un choisit de ne pas partager un emplacement. Certains navigateurs ne fonctionnent pas bien lorsque les utilisateurs font cela. Cette solution de contournement de la minuterie fonctionne parfaitement sur mon plugin Store Locator Plus WP !

2 votes

@sajith - Je ne sais pas si cette solution est maintenant dépassée avec les navigateurs FF récents. Cela fonctionnait au moment où j'ai fourni la solution parce que j'en avais besoin pour un site sur lequel je travaillais. Avez-vous testé ?

46voto

K'shin Points 286

Cela fonctionne pour moi à chaque fois :

navigator.geolocation.getCurrentPosition(getCoor, errorCoor, {maximumAge:60000, timeout:5000, enableHighAccuracy:true});

Bien que ce ne soit pas très précis. Ce qui est amusant, c'est que sur le même appareil, si j'exécute cette fonction, je suis décalé d'environ 100 mètres (à chaque fois), mais si je vais sur les cartes de Google, je trouve exactement ma position. Donc, bien que je pense que le enableHighAccuracy : true l'aide à fonctionner de manière cohérente, il ne semble pas le rendre plus précis...

0 votes

Cela a empêché firefox de refuser la demande et de renvoyer un objet timeout.

0 votes

Les 100 mètres sont la tour cellulaire à laquelle je suis relié. Il renvoie donc la position de l'antenne, pas celle de mon téléphone. Ce serait plus précis si j'étais dehors pour que le GPS se déclenche.

11 votes

Il vous repousse sans cesse de quelques mètres parce que vous avez réglé le paremètre d'âge maximum sur 60 secondes. Il place donc votre position là où vous étiez il y a 60 secondes. Réglez le maximumAge sur 10 secondes ou moins (maximumAge : 10000) et réessayez.

14voto

mvilrokx Points 476

Même chose ici, cela fonctionne parfaitement dans Chrome (stable, dev et canary) mais pas dans FF et Safari. Cela fonctionne également parfaitement sur mon iPhone et mon iPad (Safari !). Cela pourrait être dû à la relative nouveauté de cette fonctionnalité (c'est donc un bug). J'ai passé presque une semaine sur ce sujet et je n'arrive pas à le faire fonctionner sur ces navigateurs.

Voici ce que j'ai trouvé :

La première fois que vous appelez getCurrentPosition, cela fonctionne parfaitement. Tout appel ultérieur ne renvoie jamais, c'est-à-dire qu'il ne déclenche pas les fonctions successCallback ou errorCallback. J'ai ajouté quelques options de position à mon appel pour prouver mon point de vue :

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

et il s'arrête à chaque fois (après le premier appel réussi). Je pensais pouvoir résoudre le problème avec maximumAge, mais cela ne semble pas non plus fonctionner comme il se doit :

navigator.geolocation.getCurrentPosition(successCallback, errorCallback,  {maximumAge:60000, timeout: 2000});

cela devrait empêcher l'appel de la fonction getCurrentPosition si vous l'appelez dans les 60 secondes, mais il ignore cela (cependant, cela pourrait être dû au fait que je rafraîchis ma page pour déclencher le deuxième appel, je ne suis pas sûr que cela soit persistant d'un appel à l'autre).

Au fait, même exemples de google échouent sur ces navigateurs, ce qui me porte à croire qu'il s'agit effectivement de bogues de navigateur. Essayez, chargez-la deux fois dans Safari et elle ne fonctionnera pas la deuxième fois.

Si quelqu'un trouve une solution à ce problème, S'IL VOUS PLAÎT faites-le moi savoir :-)

A la vôtre.

0 votes

J'ai exactement le même problème que vous, ça marche pour le premier appel mais jamais pour les suivants, si quelqu'un trouve une solution je serais très intéressé... @xiaohouzi79 votre solution se termine à chaque fois (sauf pour le premier appel) dans geolocFail()

13voto

Mark Points 3549

Vous n'obtenez pas de message d'erreur car il n'y a pas de délai d'attente par défaut (du moins je pense). J'ai eu le même problème avec firefox, mais pour moi firefox donne toujours un timeout. Vous pouvez définir un délai d'attente vous-même comme ceci.

Ma fonction fonctionne très bien dans chrome mais j'obtiens un timeout à chaque fois dans firefox.

    navigator.geolocation.getCurrentPosition(
        function(position) {
            //do succes handling
        },
        function errorCallback(error) {
            //do error handling
        },
        {
            timeout:5000
        }
    );

Je vous recommande de surveiller attentivement vos erreurs. Soyez prévoyant pour tout. Ayez un plan de secours pour tout. J'utilise des valeurs par défaut ou des valeurs de ma base de données au cas où les géolocalisations de Google et de Navigator échouent.

10 votes

Pour votre information, maximumAge fait référence à l'ancienneté des données de localisation dans le cache. En le fixant à l'infini, vous êtes assuré d'obtenir une version en cache. Une valeur de 0 force l'appareil à récupérer la position.

1 votes

Rétrogradé parce que maximumAge : Infinity va vous foutre en l'air comme indiqué ci-dessus, cela signifie forcer l'utilisation de la valeur en cache.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X