Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added ES6 GeolocationThrottle version and removed jQuery from example page #1

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
97 changes: 54 additions & 43 deletions example.html
Original file line number Diff line number Diff line change
@@ -1,44 +1,55 @@
<!DOCTYPE html>
<html>
<head>
<title>GeolocationThrottle Example</title>
</head>
<body>
<h1>GeolocationThrottle Example</h1>

<p>
This example will print the lat/lng of the current location, at most once every 5 seconds.
<br><br>
<button id="start">Start (watchPosition)</button>
<button id="stop">Stop (clearWatch)</button>
</p>

<div id="error"></div>
<ul id="positions"></ul>

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<script src="geolocation-throttle.js"></script>
<script>
if(window.navigator && window.navigator.geolocation) {
var watchId = null;
$("#start").click(function() {
var startTime = new Date();
watchId = GeolocationThrottle.watchPosition(function(position) {
var timeEllapsed = (new Date() - startTime) / 1000.0;
$('<li>' + timeEllapsed + ' seconds: ' + position.coords.latitude + ', ' + position.coords.longitude + '</li>').appendTo($("#positions"));
}, function() {
$("#error").html("Could not get position. Have you allowed your browser and this website to check it?");
}, {
throttleTime: 5000, // here we specify that we want a geolocation callback at most once every 5 seconds
})
});

$("#stop").click(function() {
GeolocationThrottle.clearWatch(watchId);
});
} else {
$("#error").html("Your browser doesn't seem to support the geolocation API");
}
</script>
</body>
</html>
<html lang="en">
<head>
<title>GeolocationThrottle Example</title>
<style>
#error {
color: maroon;
}
</style>
</head>
<body>
<h1>GeolocationThrottle Example</h1>
<p>
This example will print the lat/lng of the current location, at most once every 5 seconds.

<br>
<br>
<button id="start">Start (watchPosition)</button>
<button id="stop">Stop (clearWatch)</button>
</p>
<div id="error"></div>
<ul id="positions"></ul>
</body>
<script src="geolocation-throttle-es6.js"></script>
<script>
const startButton = document.getElementById("start");
const stopButton = document.getElementById("stop");
const error = document.getElementById("error");
const positions = document.getElementById("positions");

if (window.navigator && window.navigator.geolocation) {
let watchId = null;

startButton.onclick = () => {
const startTime = new Date();
watchId = GeolocationThrottle.watchPosition(position => {
const timeElapsed = (new Date() - startTime) / 1000.0;

const locationRecord = document.createElement("li");
locationRecord.innerHTML = `<li>${timeElapsed} seconds: ${position.coords.latitude}, ${position.coords.longitude}</li>`;
positions.appendChild(locationRecord);
locationRecord.scrollIntoView({ behavior: "smooth" });
},
() => error.textContent = "Could not get position. Have you allowed your browser and this website to check it?",
{
throttleTime: 5000 // here we specify that we want a geolocation callback at most once every 5 seconds
});
};

stopButton.onclick = () => GeolocationThrottle.clearWatch(watchId);
} else {
error.textContent = "Could not get position. Have you allowed your browser and this website to check it?";
}
</script>
</html>
78 changes: 78 additions & 0 deletions geolocation-throttle-es5.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
(function (window) {
window.GeolocationThrottle = {
// a mapping of watchId => timeoutId that can be used to clear position watching
_timeoutIds: {},

/**
* Works just like navigator.geolocation.watchPosition, but adds one extra argument
* (throttleTime) to the options object, and makes sure that only one location callback
* is made per throttleTime timespan.
*
* Assumes that the browser supports navigator.geolocation, so one should still check for
* that. The single purpose of this lib is to throttle the location callbacks.
*/
watchPosition: function (callback, errorCallback, options) {
var throttleTime = (!options ? 0 : options.throttleTime || 0);
var bufferedArguments = null;
var lastCall = null;
var timeoutId = null;
var watchId = null;

watchId = navigator.geolocation.watchPosition(function () {
// update bufferedArguments
bufferedArguments = arguments;

if (!lastCall) {
//console.log("calling immediately initially");
lastCall = new Date();
callback.apply(this, arguments);
} else if (!timeoutId) {
// check if we've already passed the buffer time, in which case
// we'll call the callback immediately
if (new Date() - lastCall > throttleTime) {
//console.log("calling immediately since time has already passed");
lastCall = new Date();
callback.apply(this, arguments);
} else {
// if not enough time has passed since the last callback, we'll schedule
// a callback in the future
var that = this;
//console.log("call scheduled");
timeoutId = setTimeout(function () {
//console.log("Call");
lastCall = new Date();
callback.apply(that, bufferedArguments);

timeoutId = null;
window.GeolocationThrottle._timeoutIds[watchId] = null;
}, throttleTime - (new Date() - lastCall));

// we store the timeout id so that we can clear the timeout if clearWatch
// is called before the setTimeout fires
window.GeolocationThrottle._timeoutIds[watchId] = timeoutId;
}
} else {
// we already have a scheduled call
//console.log("skipping call");
}
}, errorCallback, options);
return watchId;
},

/**
* Calls navigator.geolocation.clearWatch for the given watchId, but also
* clears any timeout that has been set up by GeolocationThrottle to make
* sure that no more callback for this watchId is called.
*/
clearWatch: function (watchId) {
navigator.geolocation.clearWatch(watchId);

// if there's a scheduled watch position callback we'll clear it
var timeoutId = window.GeolocationThrottle._timeoutIds[watchId];
if (timeoutId) {
clearTimeout(timeoutId);
window.GeolocationThrottle._timeoutIds[watchId] = null;
}
}
};
})(window);
74 changes: 74 additions & 0 deletions geolocation-throttle-es6.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
{
window.GeolocationThrottle = {
// a mapping of watchId => timeoutId that can be used to clear position watching
_timeoutIds: new Map(),

/**
* Works just like navigator.geolocation.watchPosition, but adds one extra argument
* (throttleTime) to the options object, and makes sure that only one location callback
* is made per throttleTime timespan.
*
* Assumes that the browser supports navigator.geolocation, so one should still check for
* that. The single purpose of this lib is to throttle the location callbacks.
*/
watchPosition: (callback, errorCallback, options) => {
const throttleTime = (!options ? 0 : options.throttleTime || 0);
let lastCall = null;
let timeoutId = null;

const watchId = navigator.geolocation.watchPosition(function () {
if (!lastCall) {
//console.log("calling immediately initially");
lastCall = new Date();
callback.apply(this, arguments);
} else if (!timeoutId) {
// check if we've already passed the buffer time, in which case
// we'll call the callback immediately
if (new Date() - lastCall > throttleTime) {
//console.log("calling immediately since time has already passed");
lastCall = new Date();
callback.apply(this, arguments);
} else {
// if not enough time has passed since the last callback, we'll schedule
// a callback in the future
//console.log("call scheduled");

const timeout = throttleTime - (new Date() - lastCall);
timeoutId = setTimeout(() => {
//console.log("Call");
lastCall = new Date();
callback.apply(this, arguments);

timeoutId = null;
window.GeolocationThrottle._timeoutIds.delete(watchId);
}, timeout);

// we store the timeout id so that we can clear the timeout if clearWatch
// is called before the setTimeout fires
window.GeolocationThrottle._timeoutIds.set(watchId, timeoutId);
}
} else {
// we already have a scheduled call
//console.log("skipping call");
}
}, errorCallback, options);
return watchId;
},

/**
* Calls navigator.geolocation.clearWatch for the given watchId, but also
* clears any timeout that has been set up by GeolocationThrottle to make
* sure that no more callback for this watchId is called.
*/
clearWatch: watchId => {
navigator.geolocation.clearWatch(watchId);

// if there's a scheduled watch position callback we'll clear it
const timeoutId = window.GeolocationThrottle._timeoutIds.get(watchId);
if (timeoutId) {
clearTimeout(timeoutId);
window.GeolocationThrottle._timeoutIds.delete(watchId);
}
}
};
}
78 changes: 0 additions & 78 deletions geolocation-throttle.js

This file was deleted.