Reputation: 868
I have a specific issue with the Geolocation api. This is my scenario:
Geolocation.getCurrentPosition
—
Is there a way to make this work without the browser refresh ?
Here is the jsbin link: https://output.jsbin.com/pihenud
Upvotes: 2
Views: 2630
Reputation: 868
Finally, I was able to solve this problem using an iFrame hack.
Here is the solution:
Instead of asking the permission in the main window, create an iFrame dynamically and call the geolocation.getCurrentPosition
inside it. Now, we can use the window.postMessage
to pass the position data to the parent browser window.
When we have to retry the geolocation request again, we just need to reload the iframe -- This will have the new site settings.
Here is the iframe code if anyone wants to try:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Namshi Geolocation</title>
</head>
<body>
<script type="text/javascript">
var sendMessage = function(result){
window.postMessage(JSON.stringify(result), window.location.origin);
};
var triggerGeolocationRequest = function(){
var options = {
enableHighAccuracy: true,
timeout: 10000,
maximumAge: 0
};
var result;
if(window.navigator.geolocation){
window.navigator.geolocation.getCurrentPosition(function(position){
var result = {
type: 'success',
data: {lat: position.coords.latitude, lng: position.coords.longitude}
};
sendMessage(result);
}, function(err){
var result = {
type: 'error',
data: { message: err.message, code: err.code }
};
sendMessage(result);
}, options)
} else {
result = {
type: 'error',
data: { message: 'No Geolocation API' }
};
sendMessage(result);
}
};
window.addEventListener('load', triggerGeolocationRequest);
</script>
</body>
</html>
And in your application code, you can have a utility to inject the iFrame. See the below code:
utils.getCurrentPosition = function(){
return new Promise(function(resolve, reject){
var ifr = document.createElement('iframe');
ifr.style.opacity = '0';
ifr.style.pointerEvents = 'none';
ifr.src = location.origin + '/geo.html'; // the previous html code.
document.body.appendChild(ifr);
ifr.contentWindow.addEventListener('message', function(message){
message = JSON.parse(message.data);
if(message.type === 'success'){
resolve(message.data);
} else {
reject(message.data);
}
document.body.removeChild(ifr);
});
});
};
Upvotes: 5