I'm using navigator.geolocation.watchPosition function to check if the browser's location is on or not. But this function is getting called more than once (without page load). For example if i switch to another tab and go back to the page's tab it gets called.
My code is
<script>
navigator.geolocation.watchPosition(function (position) {
alert("i'm tracking you!");
},
function (error) {
if (error.code == error.PERMISSION_DENIED){
alert("you denied me :-(");
}
});
</script>
How can i call that function only once?
Just keep track of whether the watchPosition function has fired your function or not:
var firedAlready = false;
navigator.geolocation.watchPosition(function (position) {
if(!firedAlready) {
alert("i'm tracking you!");
firedAlready = true;
}
},
function (error) {
if (error.code == error.PERMISSION_DENIED){
alert("you denied me :-(");
}
});
Try to create an enclosure for your code! This will make sure it's only performed once.
var something = (function() {
var executed = false;
return function () {
if (!executed) {
executed = true;
// do something
}
};
})();
Also consider disabling the event handler with navigator.geolocation.clearWatch().
E.g.:
var id;
id = navigator.geolocation.watchPosition(function (position) {
alert("i'm tracking you!");
navigator.geolocation.clearWatch(id);
},
function (error) {
if (error.code == error.PERMISSION_DENIED){
alert("you denied me :-(");
// I suspect this is actually unnecessary since we were denied.
navigator.geolocation.clearWatch(id);
}
});
For more details check the MDN page about Geolocation.clearWatch().
You can clear position listener when you have already got the result.
enter link description here
Or you maybe use navigator.geolocation.getCurrentPostion to test whether is on or off.
You need to save the status of checking the permission in local storage for long duration use or better use cookies for that site and save the preferences there.
If you only do a variable when the page is reloaded the variable is reinitialized.
Your data need to be persistent.
Start from here if you are new with cookies
http://www.w3schools.com/js/js_cookies.asp
Related
I'm building a new site and I'm trying to get a client's coords through the browser using navigator.geolocation. It seems to do nothing at all. It doesn't throw an error or call the callback function. I went to another website using geolocation and it worked. My browser doesn't even ask for my permission on my site. I'm stumped. Thanks for your thoughts.
<script>
navigator.geolocation.getCurrentPosition(getCoor, errorCoor, {maximumAge:60000, timeout:5000, enableHighAccuracy:true});
function getCoor(pos)
{
var c = pos.coords;
alert(c.latitude);
}
function errorCoor
{
alert("FAILED!");
}
</script>
EDIT: Here is an exact copy and paste of my script:
$(document).ready(function(){
$("#c-other-source").hide();
$("#c-name").focus();
$("#c-phone").mask('(000) 000-0000');
$("#c-source").change(function(){
if ($(this).val() == 7)
{
$("#c-other-source").fadeIn("slow", function(){
$(this).focus();
});
}
});
$("#c-loc").focus(function(){
navigator.geolocation.getCurrentPosition(getCoor, errorCoor, {maximumAge:60000, timeout:5000, enableHighAccuracy:true});
});
});
function getCoor(pos)
{
alert(pos.latitude);
}
function errorCoor()
{
alert("failed");
}
Actually, it is throwing the error function now...
I wrote a script to do some automated actions on a website (which is not mine).
That website is some kind of online shop for a pc game. The user selects an item and clicks a "withdraw" button. When the website is under heavy load (quite often), the user often gets a message saying "Heavy load - try again!" and has to click the same button again and again until he either gets the item or receives a message saying "The item was already sold!".
Everything is running inside a chrome extension!
My script does the following:
Add an onClick event to the button to run a function
Click "withdraw"
Read the message that comes from the website
Depends on the message:
"Offer is being sent..." - Do nothing and read again after interval
"Item was already sold!" - Stop the interval
"Heavy load - try again!" - Click an element to remove the message and "withdraw" again
The problem:
The interval is set to 2000ms, but the script just seems to be spamming the withdraw button nonstop and it seems to ignore the clearInterval().
My code:
function buy() {
//Get the innerHTML for the box that displays the message
var message = document.getElementsByClassName("pm-content")[0].innerHTML;
//Message: Offer is being sent! - DO NOTHING!
if (message == "Please wait while your trade offer is being sent...") {
console.log("Loading: Going on!")
}
//Message: Item is gone! - STOP EVERYTHING!
if (message == "Items unavailable") {
console.log("Unavailable: Stopping!")
clearInterval(buyInterval);
}
//Message: Transaction successfull! - STOP EVERYTHING
if (message.includes("Trade offer has been sent! Code: ")) {
console.log("Success: Stopping!")
clearInterval(buyInterval);
}
if (message == "Heavy load! - Try again!") {
console.log("Overload: Going on!")
document.getElementById("pgwModal").click(); //Click to remove the message
document.getElementById("withdraw").click(); //Click withdraw again
}
}
function forceBuy() {
buyInterval = setInterval(function(){ buy() }, 2000);
}
var button = document.getElementById("withdraw");
withdraw.onclick=function(){ forceBuy () };
Any help is appreciated!
Edit_1
Code right now:
(function(){ //creating isolated scope to avoid using global variables.
var buyInterval; // declaring sharing variables.
function buy() {
var message = document.getElementsByClassName("pm-content")[0].innerHTML;
if (message == "Please wait while your trade offer is being sent...<br><small>(this might take up to 5 minutes)</small>") {
console.log("Loading: Going on!")
}
if (message == "You cannot afford that withdrawal.") {
console.log("Broke: Stopping!")
document.getElementById("pgwModal").click();
clearInterval(buyInterval);
}
if (message == "Items unavailable") {
console.log("Unavailable: Stopping!")
document.getElementById("pgwModal").click();
clearInterval(buyInterval);
}
if (message.includes("Trade offer has been sent!")) {
console.log("Success: Stopping!")
clearInterval(buyInterval);
}
if (message.includes("missing")) {
console.log("Missing: Stopping")
document.getElementById("pgwModal").click();
clearInterval(buyInterval);
}
if (message == "You can have only one pending deposit or withdrawal.") {
console.log("Pending: Stopping!")
document.getElementById("pgwModal").click();
clearInterval(buyInterval);
}
if (message == "Too many active trades") {
console.log("Overload: Going on!")
document.getElementById("pgwModal").click();
document.getElementById("withdraw").click();
}
}
function forceBuy() {
return setInterval(function(){ buy(); }, 2000); // not necessary but // will be more readable
}
var button = document.getElementById("withdraw");
withdraw.onclick=function(){ //making a closure to catch buyInterval variable
buyInterval = forceBuy ();
};
}())
Thanks to Vitalii for this code - It seems to work better now since it's not constantly spamming the button anymore. Sadly, the other problem persists: If the script reaches for example this part of the code:
if (message.includes("Trade offer has been sent!")) {
console.log("Success: Stopping!")
clearInterval(buyInterval);
}
It successfully reads the message and prints out "Success: Stopping!" - once every two seconds ... ongoing until i stop it from doing that by hand. It seems like clearInterval(buyInterval); is still being ignored.
What am I doing wrong here?
(function(){ //creating isolated scope to avoid using global variables.
var buyInterval; // declaring sharing variables.
function buy() {
... buying action
}
function forceBuy() {
return setInterval(function(){ buy(); }, 2000); // not necessary but // will be more readable
}
var button = document.getElementById("withdraw");
withdraw.onclick=function(){ //making a closure to catch buyInterval variable
buyInterval = forceBuy ();
};
}())
rewrite your forceBuy function like this -
function forceBuy() {
if(buyInterval) clearInterval(buyInterval);
buyInterval = setInterval(function(){ buy() }, 2000);
}
I am trying to determine when a user closes their connection. The problem is that, when I try to use this._session.socket.on("close",...) it also registers when the user refreshes.
Here is my code:
Meteor.publish("friends", function () {
var id = this._session.userId;
this._session.socket.on("close", Meteor.bindEnvironment(function()
{
// This logs when the user disconnects OR refreshes
console.log(id);
}, function(e){console.log(e)}))
return Meteor.users.find({...});
});
How do I differentiate between a refresh and a real disconnection?
EDIT: I would really like to avoid using a 'keep alive' function if possible.
Ok, this is a little bit hacky but I'm not sure if there is a better solution. This requires the mizzao:user-status package. The way I solved this problem is to call a meteor method inside the "on close" function that starts polling the database at 5 second intervals and checks if the user's status is online. After a set amount of time (I said 65 seconds), if the user has come online I know it was a refresh.
Anyway, the above is a little bit confusing, so here is the code:
//server
Meteor.publish("some_collection", function(){
var id = this._session.userId;
this._session.socket.on("close", Meteor.bindEnvironment(function(){
Meteor.call("connectionTest", id);
}, function(e){console.log(e)}));
return Meteor.users.find({..});
});
//Meteor method
Meteor.methods({
connectionTest: function(userId){
this.unblock();
var i = 0;
var stop = false;
var id = Meteor.setInterval(function(){
var online = Meteor.users.findOne(userId).status.online;
if(!online){
console.log("offline");
}
else{
stop = true;
console.log("still online");
}
i++;
if(stop || i > 12){
if(online){
//do something
}
else{
// do something else
}
Meteor.clearInterval(id);
}
}, 5000);
}
});
I have an app which invokes a WebService (callPathsToMultiTiffWS) which have two possibilities:
complete = true
complete = false
in the case complete = false I want to show a dialog which notifies to user than webService failed and two buttons:
retry action (reinvoke WS)
Exit
this is my code so far:
callPathsToMultiTiffWS(UID_KEY[9], stringCapturePaths, UID_KEY[1], UID_KEY[2], UID_KEY[3], UID_KEY[4], UID_KEY[5], UID_KEY[6]).then(
function (complete) {
if (complete == true) {//if true, it stores the id of the picture to delete
Windows.UI.Popups.MessageDialog("WS executed successfully", "Info").showAsync().then(function (complete) {window.close();});
} else {
var messageDialogPopup = new Windows.UI.Popups.MessageDialog("An error occur while calling WS, retry??", "Info");
messageDialogPopup.commands.append(new Windows.UI.Popups.UICommand('Retry', function () { /*code for recall element*/ }));
messageDialogPopup.commands.append(new Windows.UI.Popups.UICommand('Exit', function () { /*code for exit*/ }));
messageDialogPopup.showAsync();
_divInput.innerHTML = "";
}
},
function (error) { console.log("function error"); });
This works good so far, but I want the recall feature working
so I thought to embedd my code inside a loop like this
var ban = true;
while (true) {
callPathsToMultiTiffWS(UID_KEY[9], stringCapturePaths, UID_KEY[1], UID_KEY[2], UID_KEY[3], UID_KEY[4], UID_KEY[5], UID_KEY[6]).then(
function (complete) {
if (complete == true) {//if true, it stores the id of the picture to delete
Windows.UI.Popups.MessageDialog("WS executed successfully", "Info").showAsync().then(function (complete) { window.close(); });
} else {
var messageDialogPopup = new Windows.UI.Popups.MessageDialog("An error occur while calling WS, retry??", "Info");
messageDialogPopup.commands.append(new Windows.UI.Popups.UICommand('Retry', function () { ban == true; }));
messageDialogPopup.commands.append(new Windows.UI.Popups.UICommand('Exit', function () { ban == false; }));
messageDialogPopup.showAsync().then(function (complete) {
console.log("no ps no");
});
}
},
function (error) { console.log("function error"); });
if (ban == false) break;
}
this loop executes the webService, but it doesn't wait for user interaction to trigger the webservice by touching one of the buttons, it is an endless loop with calls to my webService, how to fix this??
thanks in advance for the support
If I'm not missing something, it looks like the error is caused because your code isn't designed to run the next set of tasks after the asynchronous call to showAsync returns. Because the call to showAsync is non-blocking, the while loop will start over again and make another call to the Web service. And because THAT call (callPathsToMultiTiffWS) is also non-blocking, the loop will start over again, triggering another call to callPathsToMultiTiffWS. And over again, and again.
My recommendation is to break out the next call to the Web service so that it will only be triggered when the user makes a selection. If you separate your concerns (move the calls to the Web service into different function or module than the UI that informs the user of an issue), then you can probably fix this.
Kraig BrockSchmidt has a great blog post about the finer details of Promises:
http://blogs.msdn.com/b/windowsappdev/archive/2013/06/11/all-about-promises-for-windows-store-apps-written-in-javascript.aspx
-edit-
Here's some code that I wrote to try to demonstrate how you might accomplish what you're trying:
function tryWebServiceCall(/* args */) {
var url = "some Web service URL";
return new WinJS.xhr({ url: url }).then(
function (complete) {
if (complete) {
return new Windows.UI.Popups.MessageDialog("WS executed successfully", "Info").showAsync().then(
function () { /*do something */ });
} else {
var messageDialogPopup = new Windows.UI.Popups.MessageDialog("An error occur while calling WS, retry??", "Info");
messageDialogPopup.commands.append(new Windows.UI.Popups.UICommand('Retry', function () {
return tryWebServiceCall( /* args */);
}));
messageDialogPopup.commands.append(new Windows.UI.Popups.UICommand('Exit', function () { return; }));
return messageDialogPopup.showAsync();
}
});
}
Rewriting the question -
I am trying to make a page on which if user leave the page (either to other link/website or closing window/tab) I want to show the onbeforeunload handeler saying we have a great offer for you? and if user choose to leave the page it should do the normal propogation but if he choose to stay on the page I need him to redirect it to offer page redirection is important, no compromise. For testing lets redirect to google.com
I made a program as follows -
var stayonthis = true;
var a;
function load() {
window.onbeforeunload = function(e) {
if(stayonthis){
a = setTimeout('window.location.href="http://google.com";',100);
stayonthis = false;
return "Do you really want to leave now?";
}
else {
clearTimeout(a);
}
};
window.onunload = function(e) {
clearTimeout(a);
};
}
window.onload = load;
but the problem is that if he click on the link to yahoo.com and choose to leave the page he is not going to yahoo but to google instead :(
Help Me !! Thanks in Advance
here is the fiddle code
here how you can test because onbeforeunload does not work on iframe well
This solution works in all cases, using back browser button, setting new url in address bar or use links.
What i have found is that triggering onbeforeunload handler doesn't show the dialog attached to onbeforeunload handler.
In this case (when triggering is needed), use a confirm box to show the user message. This workaround is tested in chrome/firefox and IE (7 to 10)
http://jsfiddle.net/W3vUB/4/show
http://jsfiddle.net/W3vUB/4/
EDIT: set DEMO on codepen, apparently jsFiddle doesn't like this snippet(?!)
BTW, using bing.com due to google not allowing no more content being displayed inside iframe.
http://codepen.io/anon/pen/dYKKbZ
var a, b = false,
c = "http://bing.com";
function triggerEvent(el, type) {
if ((el[type] || false) && typeof el[type] == 'function') {
el[type](el);
}
}
$(function () {
$('a:not([href^=#])').on('click', function (e) {
e.preventDefault();
if (confirm("Do you really want to leave now?")) c = this.href;
triggerEvent(window, 'onbeforeunload');
});
});
window.onbeforeunload = function (e) {
if (b) return;
a = setTimeout(function () {
b = true;
window.location.href = c;
c = "http://bing.com";
console.log(c);
}, 500);
return "Do you really want to leave now?";
}
window.onunload = function () {
clearTimeout(a);
}
It's better to Check it local.
Check out the comments and try this: LIVE DEMO
var linkClick=false;
document.onclick = function(e)
{
linkClick = true;
var elemntTagName = e.target.tagName;
if(elemntTagName=='A')
{
e.target.getAttribute("href");
if(!confirm('Are your sure you want to leave?'))
{
window.location.href = "http://google.com";
console.log("http://google.com");
}
else
{
window.location.href = e.target.getAttribute("href");
console.log(e.target.getAttribute("href"));
}
return false;
}
}
function OnBeforeUnLoad ()
{
return "Are you sure?";
linkClick=false;
window.location.href = "http://google.com";
console.log("http://google.com");
}
And change your html code to this:
<body onbeforeunload="if(linkClick == false) {return OnBeforeUnLoad()}">
try it
</body>
After playing a while with this problem I did the following. It seems to work but it's not very reliable. The biggest issue is that the timed out function needs to bridge a large enough timespan for the browser to make a connection to the url in the link's href attribute.
jsfiddle to demonstrate. I used bing.com instead of google.com because of X-Frame-Options: SAMEORIGIN
var F = function(){}; // empty function
var offerUrl = 'http://bing.com';
var url;
var handler = function(e) {
timeout = setTimeout(function () {
console.log('location.assign');
location.assign(offerUrl);
/*
* This value makes or breaks it.
* You need enough time so the browser can make the connection to
* the clicked links href else it will still redirect to the offer url.
*/
}, 1400);
// important!
window.onbeforeunload = F;
console.info('handler');
return 'Do you wan\'t to leave now?';
};
window.onbeforeunload = handler;
Try the following, (adds a global function that checks the state all the time though).
var redirected=false;
$(window).bind('beforeunload', function(e){
if(redirected)
return;
var orgLoc=window.location.href;
$(window).bind('focus.unloadev',function(e){
if(redirected==true)
return;
$(window).unbind('focus.unloadev');
window.setTimeout(function(){
if(window.location.href!=orgLoc)
return;
console.log('redirect...');
window.location.replace('http://google.com');
},6000);
redirected=true;
});
console.log('before2');
return "okdoky2";
});
$(window).unload(function(e){console.log('unloading...');redirected=true;});
<script>
function endSession() {
// Browser or Broswer tab is closed
// Write code here
alert('Browser or Broswer tab closed');
}
</script>
<body onpagehide="endSession();">
I think you're confused about the progress of events, on before unload the page is still interacting, the return method is like a shortcut for return "confirm()", the return of the confirm however cannot be handled at all, so you can not really investigate the response of the user and decide upon it which way to go, the response is going to be immediately carried out as "yes" leave page, or "no" don't leave page...
Notice that you have already changed the source of the url to Google before you prompt user, this action, cannot be undone... unless maybe, you can setimeout to something like 5 seconds (but then if the user isn't quick enough it won't pick up his answer)
Edit: I've just made it a 5000 time lapse and it always goes to Yahoo! Never picks up the google change at all.