getCurrentPosition与watchPosition
watchPosition会监视你的移动,并在位置改变时向你报告位置。watchPPosition方法看上去确实与getCurrentPosition方法很像,不过行为稍有不同,每次位置比阿奴啊时会重复调用你的成功处理程序
watchPosition调用步骤:
- 你的应用watchPosition,传入一个成功处理函数
- watchPosition在后台不断监视你的位置
- 你的位置改变时,watchPostion调用成功处理函数来报告你的新位置
- watchPostion继续监视你的位置(并向成功处理程序报告),直至你调用clearWatch将它清除
HTML代码
我 们已HTML5COL学院中级课程相关章节的课程为基础,再向HTML增加几个按钮,从而能开始和结束跟踪你的位置;我们设置开始按钮是因为用户不想一直 被跟踪,他们通常希望对此有些控制;设置结束按钮,是考虑到对于移动设备来说,不停检查用户的位置是一个相当耗费电的操作,如果一直打开跟踪,会严重影响 电池寿命:
注: 实时跟踪用户可能非常耗电。一定要为用户提供信息,指出日前正在跟踪,另外还要提供相应的一些控件
<!DOCTYPE html> <html> <head> <meta='keywords' content='HTML5COL学院,HTML5COL,CSS3,HTML5COL,编码社区'> <script> <!--script代码,见HTML5COL学院的应用课程:Geolocation API应用:计算两地距离---> </script> </head> <body> <form> <input type="button" id="watch" value="Watch me"> <input type="button" id="clearWatch" value="Clear watch"> </form> <p>position:</p> <div id="location" > </div> <div id="distance" > </div> </body> </html>
代码释义: 我们增加了一个表单元素,其中包括两个按钮,一个用来启动监视,id为'watch',另一个用来清除监视,id为'clearwatch';并且 我们用原来的
为按钮添加程序
只 有在支持地理定位情况下我们才会在getMyLocation函数中增加按钮点击处理程序。另外,由于要用两个按钮控制所有地理位置定位跟踪,所以要从 getMyLocation删除现在的getCurrentPosition调用。下面删除这个代码,再增加两个处理程序:watchPostion对应 监视按钮,clearWatch对应清除按钮:
function getMyLocation() { if (navigator.geolocation) { var watchButton = document.getElementById("watch"); watchButton.onclick = watchLocation; var clearWatchButton = document.getElementById("clearWatch"); clearWatchButton.onclick = clearWatch; } else { alert("Oops, no geolocation support"); } }
代码释义: 如果浏览器支持地理定位,则我们会增加按钮点击处理程序;如果不支持地理定位,则增加这些处理程序毫无意义;上述代码中我们调用watchLocation来启动监视,调用clearWatch停止监视
编写watchLocation处理程序
目 前,我们要做的工作是:用户点击监视按钮时,他们希望开始跟踪他们的位置。所以我们将使用geolocation.watchPosition方法开始监 视他们的位置。geolocation.watchPosition方法有有两个参数程序:一个成功处理程序和一个错误处理程序,所以我们将使用原来已有 的两个处理程序。它还会返回一个watchId,可以在任何时刻使用这个id取消监视行为。我们把这个watchId放在一个全局变量中,为清除按钮编写 点击处理程序时会用到这个变量。一下是watchLocation函数和watchId的代码:
var watchId = null; function watchLocation() { watchId = navigator.geolocation.watchPosition( displayLocation, displayError); }
代码释义: 在文件最上面增加watchId作为一个全局变量。我们把它初始化为null,以后还需要把这个变量清除监视;调用watchLocation方法,传入前面编写的成功处理程序displayLocation和现有的错误处理程序displayError
编写watchLocation处理程序
现在来编写处理程序清除监视行为。为此需要得到watchId,并把它传递到geolocation.clearWatch方法
function clearWatch() { if (watchId) { navigator.geolocation.clearWatch(watchId); watchId = null; } }
最后,对displayLocation做小的修改
还 需要做一个很小的修改,设计前面编写的Google Maps代码。在这代码中,我们调用了showMap来显示Google Map。showMap会在页面中创建一个地图,这件事你只希望做一次。不过,要记住,开始用watchPosition监视你的位置时,每次位置有更新 时都会调用displayLocation
要确保只调用一次showMap,首先查看这个地图是否存在,如果不存在,则调用showMap。否则,说明showMap已经调用过(而且已经创建了地图),所以不需要再调用这个函数了:
function displayLocation(position) { var latitude = position.coords.latitude; var longitude = position.coords.longitude; var div = document.getElementById("location"); div.innerHTML = "You are at Latitude: " + latitude + ", Longitude: " + longitude; div.innerHTML += " (with " + position.coords.accuracy + " meters accuracy)"; var km = computeDistance(position.coords, ourCoords); var distance = document.getElementById("distance"); distance.innerHTML = "You are " + km + " km from the WickedlySmart HQ"; if (map == null) { showMap(position.coords); //如果还没有调用showMap,则调用这个函数,否则不需要每次调用displayLocation时都调用showMap } }
确保您使用的是移动设备
当您离开HTML5COL学院大门时,您一直在移动,所以为了监控您的行踪,一台设备是必须的;
综合代码展示;
基本HTML代码;
<!doctype html> <html> <head> <title>Wherever you go, there you are</title> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1"> <meta charset="utf-8"> <script src="http://maps.google.com/maps/api/js?sensor=false"></script> <script src="myLoc.js"></script> <link rel="stylesheet" href="myLoc.css"> </head> <body> <form> <input type="button" id="watch" value="Watch me"> <input type="button" id="clearWatch" value="Clear watch"> </form> <div id="location"> Your location will go here. </div> <div id="distance"> Distance from HTML5COL OFFICE will go here. </div> <div id="map"> </div> </body> </html>
myLoc.js代码;
/* myLoc.js */ var watchId = null; var map = null; var ourCoords = { latitude: 47.624851, longitude: -122.52099 }; window.onload = getMyLocation; function getMyLocation() { if (navigator.geolocation) { var watchButton = document.getElementById("watch"); watchButton.onclick = watchLocation; var clearWatchButton = document.getElementById("clearWatch"); clearWatchButton.onclick = clearWatch; } else { alert("Oops, no geolocation support"); } } function displayLocation(position) { var latitude = position.coords.latitude; var longitude = position.coords.longitude; var div = document.getElementById("location"); div.innerHTML = "You are at Latitude: " + latitude + ", Longitude: " + longitude; div.innerHTML += " (with " + position.coords.accuracy + " meters accuracy)"; var km = computeDistance(position.coords, ourCoords); var distance = document.getElementById("distance"); distance.innerHTML = "You are " + km + " km from the WickedlySmart HQ"; if (map == null) { showMap(position.coords); } } // --------------------- Ready Bake ------------------ // // Uses the Spherical Law of Cosines to find the distance // between two lat/long points // function computeDistance(startCoords, destCoords) { var startLatRads = degreesToRadians(startCoords.latitude); var startLongRads = degreesToRadians(startCoords.longitude); var destLatRads = degreesToRadians(destCoords.latitude); var destLongRads = degreesToRadians(destCoords.longitude); var Radius = 6371; // radius of the Earth in km var distance = Math.acos(Math.sin(startLatRads) * Math.sin(destLatRads) + Math.cos(startLatRads) * Math.cos(destLatRads) * Math.cos(startLongRads - destLongRads)) * Radius; return distance; } function degreesToRadians(degrees) { radians = (degrees * Math.PI)/180; return radians; } // ------------------ End Ready Bake ----------------- function showMap(coords) { var googleLatAndLong = new google.maps.LatLng(coords.latitude, coords.longitude); var mapOptions = { zoom: 10, center: googleLatAndLong, mapTypeId: google.maps.MapTypeId.ROADMAP }; var mapDiv = document.getElementById("map"); map = new google.maps.Map(mapDiv, mapOptions); // add the user marker var title = "Your Location"; var content = "You are here: " + coords.latitude + ", " + coords.longitude; addMarker(map, googleLatAndLong, title, content); } function addMarker(map, latlong, title, content) { var markerOptions = { position: latlong, map: map, title: title, clickable: true }; var marker = new google.maps.Marker(markerOptions); var infoWindowOptions = { content: content, position: latlong }; var infoWindow = new google.maps.InfoWindow(infoWindowOptions); google.maps.event.addListener(marker, 'click', function() { infoWindow.open(map); }); } function displayError(error) { var errorTypes = { 0: "Unknown error", 1: "Permission denied", 2: "Position is not available", 3: "Request timeout" }; var errorMessage = errorTypes[error.code]; if (error.code == 0 || error.code == 2) { errorMessage = errorMessage + " " + error.message; } var div = document.getElementById("location"); div.innerHTML = errorMessage; } // // Code to watch the user's location // function watchLocation() { watchId = navigator.geolocation.watchPosition( displayLocation, displayError); } function clearWatch() { if (watchId) { navigator.geolocation.clearWatch(watchId); watchId = null; } }
测试地址: 在线测试