1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
|
---
title: 使用地理位置定位
slug: Web/API/Geolocation/Using_geolocation
tags:
- 地理位置 API
- 指南
translation_of: Web/API/Geolocation_API
---
<p><strong>地理位置 API</strong> 允许用户向 Web 应用程序提供他们的位置。出于隐私考虑,报告地理位置前会先请求用户许可。</p>
<h2 id="geolocation_对象">geolocation 对象</h2>
<p>地理位置 API 通过 {{domxref("NavigatorGeolocation.geolocation","navigator.geolocation")}} 提供。</p>
<p>如果该对象存在,那么地理位置服务可用。</p>
<pre class="brush: js">if ("geolocation" in navigator) {
/* 地理位置服务可用 */
} else {
/* 地理位置服务不可用 */
}
</pre>
<div class="note">
<p><strong>注意:</strong> 在 Firefox 24 和之前的浏览器中,即使 API 被禁止,代码 <code>"geolocation" in navigator</code> 也总是会得到 <code>true</code>。这在 <a href="/en-US/docs/Mozilla/Firefox/Releases/25/Site_Compatibility">Firefox 25</a> 中已经被修复 ({{ bug(884921) }})。</p>
</div>
<h3 id="获取当前定位">获取当前定位</h3>
<p>您可以调用 {{domxref("Geolocation.getCurrentPosition","getCurrentPosition()")}} 函数获取用户当前定位位置。这会异步地请求获取用户位置,并查询定位硬件来获取最新信息。当定位被确定后,定义的回调函数就会被执行。您可以选择性地提供第二个回调函数,当有错误时会被执行。第三个参数也是可选的,您可以通过该对象参数设定最长可接受的定位返回时间、等待请求的时间和是否获取高精度定位。</p>
<div class="note">
<p><strong>注意:</strong> 默认情况下,{{domxref("Geolocation.getCurrentPosition","getCurrentPosition()")}} 会尽快返回一个低精度结果,这在您不关心准确度只关心快速获取结果的情况下很有用。有 GPS 的设备可能需要一分钟或更久来获取 GPS 定位,在这种情况下 {{domxref("Geolocation.getCurrentPosition","getCurrentPosition()")}} 会返回低精度数据(基于 IP 的定位或 Wi-Fi 定位)。</p>
</div>
<pre class="brush: js">navigator.geolocation.getCurrentPosition(function(position) {
do_something(position.coords.latitude, position.coords.longitude);
});</pre>
<p>上述示例中,当获取位置后 <code>do_something()</code> 函数会被执行。</p>
<h3 id="监视定位">监视定位</h3>
<p>您可以设定一个回调函数来响应定位数据发生的变更(设备发生了移动,或获取到了更高精度的地理位置信息)。您可以通过 {{domxref("Geolocation.watchPosition","watchPosition()")}} 函数实现该功能。它与 {{domxref("Geolocation.getCurrentPosition","getCurrentPosition()")}} 接受相同的参数,但回调函数会被调用多次。错误回调函数与 {{domxref("Geolocation.getCurrentPosition","getCurrentPosition()")}} 中一样是可选的,也会被多次调用。</p>
<div class="note">
<p><strong>注意:</strong> 您可以直接调用 {{domxref("Geolocation.watchPosition","watchPosition()")}} 函数,不需要先调用 {{domxref("Geolocation.getCurrentPosition","getCurrentPosition()")}} 函数。</p>
</div>
<pre class="brush: js">var watchID = navigator.geolocation.watchPosition(function(position) {
do_something(position.coords.latitude, position.coords.longitude);
});</pre>
<p>{{domxref("Geolocation.watchPosition","watchPosition()")}} 函数会返回一个 ID,唯一地标记该位置监视器。您可以将这个 ID 传给 {{domxref("Geolocation.clearWatch()","clearWatch()")}} 函数来停止监视用户位置。</p>
<pre class="brush: js">navigator.geolocation.clearWatch(watchID);
</pre>
<h3 id="调整返回结果">调整返回结果</h3>
<p>{{domxref("Geolocation.getCurrentPosition","getCurrentPosition()")}} 和 {{domxref("Geolocation.watchPosition","watchPosition()")}} 都接受一个成功回调、一个可选的失败回调和一个可选的 <code>PositionOptions</code> 对象。</p>
<p>{{page("/zh-CN/docs/Web/API/Geolocation.getCurrentPosition","PositionOptions")}}</p>
<p>对 {{domxref("Geolocation.watchPosition()","watchPosition")}} 的调用类似于这样:</p>
<pre class="brush: js">function geo_success(position) {
do_something(position.coords.latitude, position.coords.longitude);
}
function geo_error() {
alert("Sorry, no position available.");
}
var geo_options = {
enableHighAccuracy: true,
maximumAge : 30000,
timeout : 27000
};
var wpid = navigator.geolocation.watchPosition(geo_success, geo_error, geo_options);</pre>
<p>watchPosition 实际使用示例: <a class="external" href="http://www.thedotproduct.org/experiments/geo/">http://www.thedotproduct.org/experiments/geo/</a></p>
<h2 id="描述位置">描述位置</h2>
<p>用户的位置由一个包含 <code>Coordinates</code> 对象的 <code>Position</code> 对象描述。</p>
<p>{{page("/zh-CN/docs/Web/API/Geolocation.getCurrentPosition","Position")}}</p>
<p>{{page("/zh-CN/docs/Web/API/Geolocation.getCurrentPosition","Coordinates")}}</p>
<h2 id="处理错误">处理错误</h2>
<p><code>getCurrentPosition()</code> 或 <code>watchPosition()</code> 的错误回调函数以 <code>PositionError</code> 为第一个参数。</p>
<pre class="brush: js">function errorCallback(error) {
alert('ERROR(' + error.code + '): ' + error.message);
};
</pre>
<p>{{page("/zh-CN/docs/Web/API/Geolocation.getCurrentPosition","PositionError")}}</p>
<h2 id="地理位置示例">地理位置示例</h2>
<div class="hidden">
<pre class="brush: css">body {
padding: 20px;
background-color:#ffffc9
}
p { margin : 0; }
</pre>
</div>
<h3 id="HTML">HTML</h3>
<pre class="brush: html;"><p><button onclick="geoFindMe()">Show my location</button></p>
<div id="out"></div></pre>
<p> </p>
<div id="out"> </div>
<h3 id="JavaScript">JavaScript</h3>
<pre class="brush: js;">function geoFindMe() {
var output = document.getElementById("out");
if (!navigator.geolocation){
output.innerHTML = "<p>您的浏览器不支持地理位置</p>";
return;
}
function success(position) {
var latitude = position.coords.latitude;
var longitude = position.coords.longitude;
output.innerHTML = '<p>Latitude is ' + latitude + '° <br>Longitude is ' + longitude + '°</p>';
var img = new Image();
img.src = "http://maps.googleapis.com/maps/api/staticmap?center=" + latitude + "," + longitude + "&zoom=13&size=300x300&sensor=false";
output.appendChild(img);
};
function error() {
output.innerHTML = "无法获取您的位置";
};
output.innerHTML = "<p>Locating…</p>";
navigator.geolocation.getCurrentPosition(success, error);
}
</pre>
<h3 id="在线示例">在线示例</h3>
<p>{{ EmbedLiveSample('Geolocation_Live_Example',350,410) }}</p>
<h2 id="授权请求">授权请求</h2>
<p>所有 addons.mozilla.org 上需要使用地理位置的插件必须在使用 API 前显式地请求权限。用户的响应将会存储在 <code>pref</code> 参数指定的偏好设置中。<code>callback</code> 参数指定的函数会被调用并包含一个代表用户响应的 boolean 参数。如果为 <code>true</code>,代表插件可以访问地理位置数据。</p>
<pre class="brush: js">function prompt(window, pref, message, callback) {
let branch = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefBranch);
if (branch.getPrefType(pref) === branch.PREF_STRING) {
switch (branch.getCharPref(pref)) {
case "always":
return callback(true);
case "never":
return callback(false);
}
}
let done = false;
function remember(value, result) {
return function() {
done = true;
branch.setCharPref(pref, value);
callback(result);
}
}
let self = window.PopupNotifications.show(
window.gBrowser.selectedBrowser,
"geolocation",
message,
"geo-notification-icon",
{
label: "Share Location",
accessKey: "S",
callback: function(notification) {
done = true;
callback(true);
}
}, [
{
label: "Always Share",
accessKey: "A",
callback: remember("always", true)
},
{
label: "Never Share",
accessKey: "N",
callback: remember("never", false)
}
], {
eventCallback: function(event) {
if (event === "dismissed") {
if (!done) callback(false);
done = true;
window.PopupNotifications.remove(self);
}
},
persistWhileVisible: true
});
}
prompt(window,
"extensions.foo-addon.allowGeolocation",
"Foo Add-on wants to know your location.",
function callback(allowed) { alert(allowed); });
</pre>
<h2 id="浏览器兼容性">浏览器兼容性</h2>
<div>{{ CompatibilityTable() }}</div>
<div> </div>
<div id="compat-desktop">
<table class="compat-table">
<tbody>
<tr>
<th>Feature</th>
<th>Chrome</th>
<th>Firefox (Gecko)</th>
<th>Internet Explorer</th>
<th>Opera</th>
<th>Safari</th>
</tr>
<tr>
<td>Basic support</td>
<td>5</td>
<td>{{CompatGeckoDesktop("1.9.1")}}</td>
<td>9</td>
<td>10.60<br>
Removed in 15.0<br>
Reintroduced in 16.0</td>
<td>5</td>
</tr>
</tbody>
</table>
</div>
<div id="compat-mobile">
<table class="compat-table">
<tbody>
<tr>
<th>Feature</th>
<th>Android</th>
<th>Chrome for Android</th>
<th>Firefox Mobile (Gecko)</th>
<th>Firefox OS</th>
<th>IE Mobile</th>
<th>Opera Mobile</th>
<th>Safari Mobile</th>
</tr>
<tr>
<td>Basic support</td>
<td>{{CompatUnknown()}}</td>
<td>{{CompatUnknown()}}</td>
<td>{{CompatGeckoMobile("4")}}</td>
<td>1.0.1</td>
<td>{{CompatUnknown()}}</td>
<td>10.60<br>
Removed in 15.0<br>
Reintroduced in 16.0</td>
<td>{{CompatUnknown()}}</td>
</tr>
</tbody>
</table>
</div>
<h3 id="Gecko_注释">Gecko 注释</h3>
<p>Firefox 支持根据您的 Wi-Fi 信息通过谷歌定位服务来定位。在 Firefox 和 Google 的数据交互中,Wi-Fi 接入点信息、访问令牌(类似于一个两周过期的 cookie)和用户的 IP 地址会被发送。关于数据使用情况,请查看 Mozilla 的<a class="external" href="http://www.mozilla.com/en-US/legal/privacy/" title="http://www.mozilla.com/en-US/legal/privacy/">隐私声明</a>和 Google 的<a class="external" href="http://www.google.com/privacy-lsf.html" title="http://www.google.com/privacy-lsf.html">隐私声明</a>。</p>
<p>Firefox 3.6 (Gecko 1.9.2) 增加了 Linux 上对 <a class="external" href="http://catb.org/gpsd/" title="http://catb.org/gpsd/">GPSD</a> (GPS daemon) 服务定位的支持。</p>
<h2 id="另请参阅">另请参阅</h2>
<ul>
<li>{{domxref("NavigatorGeolocation.geolocation","navigator.geolocation")}}</li>
<li><a href="/en-US/Apps/Build/gather_and_modify_data/Plotting_yourself_on_the_map">在地图上标记自己</a></li>
<li><a href="http://www.w3.org/TR/geolocation-API/" rel="external" title="http://www.w3.org/TR/geolocation-API/">w3.org 上的地理位置 API</a></li>
<li><a href="/en-US/demos/tag/tech:geolocation" title="en-US/demos/tag/tech:geolocation/">地理位置 API 的示例</a></li>
<li><a href="https://hacks.mozilla.org/2013/10/who-moved-my-geolocation/">Who moved my geolocation?</a> (Hacks blog)</li>
</ul>
|