だから私はこのjavascriptコードを持っています。 safariとchromeでは、ユーザーが場所の共有を拒否すると、本来の機能に失敗します。ただし、Firefoxではそうではありません。
感謝します。
function initGeolocation()
{
if( navigator.geolocation )
{
// Call getCurrentPosition with success and failure callbacks
navigator.geolocation.getCurrentPosition( success, fail );
}
else
{
alert("Sorry, your browser does not support geolocation services.");
}
}
var map;
function success(position)
{
var longIDText = document.getElementById('longID');
var latIDText = document.getElementById('latID');
longIDText.value = position.coords.longitude;
latIDText.value = position.coords.latitude;
document.getElementById('coordSubmitID').click();
}
function fail(error)
{
alert("FAAAAAAAAAAIIIIIIIIIL")
var Zip_code ;
while (true){
// Could not obtain location
Zip_code = Prompt("Please enter your current address or Zip code","");
if ( Zip_code == "" ) {
alert(Zip_code +" is not a valid address. Please try again.");
}
else{
break;
}
}
var zipIDText = document.getElementById('zipID');
zipIDText.value = Zip_code;
document.getElementById('coordSubmitID').click();
}
Firefoxの場合 そのようですPERMISSION_DENIED
は、「共有しない」が選択されている場合にのみ発生しますonly。ダイアログが閉じられるか、「今はしない」が選択された場合、事実上何も起こりません- mozillas geolocation demo でも、許可UIを閉じても何も起こりません。
これは、ユーザーが確認UIを閉じたため、または非同期要求を正常に開始したため、getCurrentPosition
が返される可能性があることを意味します-両者を区別する方法はないようです。
これは本当の苦痛であり、明らかに望ましくない機能です。
私が今まで待っているユーザーを保存するために使用している回避策は、タイムアウトを設定して待機スピナーが3秒後に表示されているかどうかを確認し、そうであればそれを非表示にして手動の郵便番号入力を表示することです:
var latlng;
var waitTime = 3000;
try {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function (position) {
success(position);
}, showError);
} else {
showError("NOT-SUPPORTED");
}
var t = setTimeout(function () {
if ($("#getZip div.loading").css("display") != "none") {
$("#getZip div.loading").hide();
$("#errorZip").show();
}
}, waitTime);
} catch (evt) {
alert(evt);
}
Alexleonardが指摘したように、このために見つけた唯一の信頼できるクロスブラウザソリューションは、setTimeout()
のlatLng
オプションとして、timeout
オブジェクト/変数の状態をチェックするgetCurrentPosition()
を持つことです。 ]が確実に機能しないようです。以下の例は、IE11、Chrome33、Firefox28でテストされました。
JQuery promiseを使用するより完全なソリューションについては、ここで私の要点を確認してください。 https://Gist.github.com/GFoley83/10092929
例-F12キーを押し、コンソールに貼り付けて実行します
var latLng,
geoOptions = {
enableHighAccuracy: false,
timeout: 5000, // Wait 5 seconds
maximumAge: 300000 // Valid for 5 minutes
};
var userLocationFound = function(position){
latLng = {
lat: position.coords.latitude,
lng: position.coords.longitude
};
window.console.log("User confirmed! Location found: " + latLng.lat + ", " + latLng .lng);
}
var userLocationNotFound = function(){
latLng = {
lat: -41.29247, // fallback lat
lng: 174.7732 // fallback lng
};
window.console.log("Fallback set: ", latLng);
}
window.navigator.geolocation.getCurrentPosition(userLocationFound, userLocationNotFound, geoOptions);
setTimeout(function () {
if(!latLng){
window.console.log("No confirmation from user, using fallback");
userLocationNotFound();
}else{
window.console.log("Location was set");
}
}, geoOptions.timeout + 1000); // Wait extra second
これは実際にはChromeでも問題であることに注意してください。
Chrome「サイトはあなたの場所を知りたい」という通知が表示されます-オプションとして「許可」と「拒否」を提供します。UIデザインでは、ユーザーはどちらかを選択する可能性が高くなります。 AllowまたはDenyは、navigator.geolocation.getCurrentPosition関数への回答を返しますが、ユーザーはアドバイザリ通知の右端にある「X」をクリックすることもできます。これは、「Not now」をクリックすることと本質的に同じです。 Firefoxで。
結果は関数に返されません。
この結果を可能にするために、タイマーを実装する必要があるようです。
これは設計どおりであり、明らかに問題ではありません。 https://bugzilla.mozilla.org/show_bug.cgi?id=6755 を参照してください
この機能を使用する開発者は、Firefoxのブラウザー固有の回避策を考え出す必要があります。
注目すべきは、エンドユーザーによる実際の位置情報の使用に関するFF開発者のコメントに基づいて、明らかにFirefox開発者はエンドユーザーが製品で行っていることに関する詳細なデータを収集していることです。
約束を使用します。私たちが抱えている同じ問題を解決するために、独自のバージョンの$ qを備えたangularjsを使用しています。
$scope.ByUserPosition = function () {
//http://www.w3.org/TR/geolocation-API/
var deferred = $q.defer();
deferred.promise.then(findByPosition, function (data) {
console.log('error', data);
});
var resolveBy = 1000 * 30;
navigator.geolocation.getCurrentPosition(function (position) {
deferred.resolve({ latitude: position.coords.latitude, longitude: position.coords.longitude });
}, function (err) {
deferred.reject(err);
}, {
enableHighAccuracy: true,
timeout: resolveBy,
maximumAge: 0
});
$timeout(function() {
deferred.reject('timed out');
}, resolveBy)
};
この問題の唯一の解決策は次のとおりです。
これが役立つことを願っています:)
編集(ダウン投票後)6-11-201
この回答の下で述べたように、これはユーザーが場所へのアクセスを拒否した場合の問題を解決しません。 downvoteに正しいです。タイムアウトはとにかく使用するべきものであるため、ここで答えを保持します。どの答えにも表示されません。
関数navigator.geolocation.getCurrentPosition()には、タイムアウトを送信するオプションがあります。
navigator.geolocation.getCurrentPosition(
function (position){
//do someting with position
},
function (error){
// do something with the error (like the code)
},
{timeout:10000}
);
キャッシュされた位置の年齢(maximumAge)などのその他のオプション。タイムアウトと最大時間はミリ秒単位であるため、10000 = 10秒です。
ところで、デフォルトのタイムアウトは無限です...ですので、タイムアウトを設定しないと、エラーのためにコールバックを呼び出すことはありません。
ジェイミーが答えたようなオプションで、私は言うでしょう:
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function (position) {
success(position);
}, showError, {timeout:3000});
}
Vanilla es6 Promises
を使用して、私の問題を解決します。 @LeblancMenesesの回答に触発されました。
if(navigator.geolocation) {
let promise = new Promise((resolve, reject) => {
navigator.geolocation.getCurrentPosition(
(position) => {
resolve(position)
},
(error) => {
resolve(error)
}
)
window.setTimeout(() => {
resolve({})
}, 8000)
})
promise.then((result) => {
// do something with result
})
} else {
console.log('no geolocation available')
}