I think clearInterval problems - javascript

I came here like many beginners :D So without wasting a time I will explain my problems.
http://heavenpro.lt/ukv - website of demo. There a 2 users etc.
sekret - demo
demo - demo
(for login) if you will see any error - would be happy to know to have a chance to solve it.
When users turned off (Išj. - button) demo user sees log: Waiting for student (Laukiama studento)
after sekret turn it on (Įjungt - button) everything seems okay, demo user sees active user, after clicking to next one - gives alert that was changed student and if you want to update information (to see new one) however.. after turning off (Išj. button) Works good in all browsers except IE.. Seems that clearInterval not works and after lot of sent queries and respons it pops out more than one Alert window..
Hope you understood that i mean.
var sid = "{$i->sid}";
var mid = "{$i->mid}";
var update_st = setInterval(function(){
$.post(
'ajax/check-student.php',
{ sid: sid, mid: mid },
function(resp){
if(resp == "next") {
var cf = confirm('Buvo pakeistas studentas besiginantis darbą. Ar rodyti sekantį studentą?');
clearInterval(update_st);
if (cf) {
window.location = "?";
}
else {
alert('Kai norėsite perjungti kitą vartotoją, prašome perkrauti puslapį.');
clearInterval(update_st);
}
}
else if (resp == "none") {
alert("Gynimas baigtas. Ačiū už dalyvavimą vertinimo komisijoje.");
clearInterval(update_st); // this place not works..
window.location = "?";
}
});
}, 250);
Tested lot times.. seems sometimes works normaly.. Tested on IE 9..
Of maybe can anyone offer any others ideas to do same way? Without many queries per second sending to file...

You can use setTimeout instead of setInterval, many reasons...
So you will call function that creates setTimeout! And this method will guarantee that your code will be executes iff query to server is done!
var a = function(){
var timer = setTimeout(function(){
// ok your ajax query success of error whatever
a();
console.log(2)
}, 1000);
}
a();
You must put your query inside setTimeout, and call a function after query done or whatever!
So demo

Related

Using the Notification API from a bookmarklet

I am trying to write a bookmarklet that sends me a desktop notification when CI on GitHub completes. Notification.requestPermission runs correctly, and asks me for permission, and the console.log statements run correctly, but the notification does not appear. Here is the text of the bookmarklet script:
(function() {
Notification.requestPermission().then(() => {
const search = setInterval(() => {
if (window.find("All checks have passed")) {
console.log('all checks passed');
clearTimeout(search);
new Notification('Github checks passed!');
} else {
console.log('checks pending');
}
}, 1000);
});
})();
i.e.
javascript:(function() {Notification.requestPermission().then(() => {const search = setInterval(() => {if (window.find("All checks have passed")) {console.log('all checks passed');clearTimeout(search);new Notification('Github checks passed!');} else {console.log('checks pending');}}, 1000);});})();
Is this a sandboxing thing?
I have tried with the same code you have written and tried to add few tweaks and verify the existing code.
I have seen that there not an issue with your code. I have tried to simulate the same situation with your code and it works.
In order to work on your code, I have added dummy text in the HTML body after 5 seconds of page loads, meanwhile, setTimeout function logs checks pending
After 5 seconds it a text in the body and after that it goes to search the text and the code works fine.
Here my little tweaks which might help you to identify the root cause. I guess if your code is working on these tweaks, it means that somehow in your real situation the text might not found from the HTML template.
Yes, one more thing you should keep in mind that you must allow notification when the browser asks in popup, Once you allow the show the notification, in the next attempt it will populate the notification with suggested text.
Following code, I have tried.
minify version:
javascript:(function(){Notification.requestPermission().then(()=>{let e=0;console.log("find:",window.find("All checks have passed"));const n=setInterval(()=>{if(window.find("All checks have passed"))clearTimeout(n),new Notification("Github checks passed!");else{if(5===e){const e=document.createElement("label");e.innerHTML="All checks have passed",document.body.appendChild(e)}console.log("checks pending")}e+=1},1e3)})})();
beautify version:
javascript: (function() {
Notification.requestPermission().then(() => {
let counter = 0;
console.log("find:", window.find("All checks have passed"));
const interval = setInterval(() => {
if (window.find("All checks have passed")){
clearTimeout(interval);
console.log("checks passed");
new Notification("Github checks passed!");
} else {
if (5 === counter) {
const el = document.createElement("label");
el.innerHTML = "All checks have passed";
document.body.appendChild(el);
}
console.log("checks pending");
}
counter += 1;
}, 1000)
})
})();
I have also attached the screenshots for your reference.
For your reference, this code will work in the console also it will populate the message in your console also.
Hope it might clear your idea.
This code is 100% working, so if you still face the trouble, let me know I will definitely try to help you.
As others have said, the code works as expected.
My guess is you're having problems with the setInterval function. On firefox, setInterval doesn't run when the tab isn't on focus (you also lose focus when you execute the bookmarklet from the bookmark tab).
I assume you navigated to a different tab which results in the timer stopping. Unfortunately I don't think there's an easy solution to get the result you want.
See here for reference: SetInterval not running in Firefox when lost focus on tab/window

Using location.reload on Chrome is not working as it should, using the same code in Firefox works fine

I am making a Snake game using Javascript and checking if the user has touched the borders, if he has than it's gameover and a game over function is called which shows a confirm box with it's content based on the language of the html file because i have 2 html files: one for French and one for English.
this.alert = alert;
this.gameOver = function() {
const langCheck = document.getElementById("html").lang;
if (langCheck === "fr") {
alert = confirm("\t\tPerdu!\n\n Votre longueur était: " + this.eaten);
} else {
alert = confirm(
"\t\tGame Over!\n\n Your snake length was: " + this.eaten
);
}
console.log(alert);
if (alert === true) {
document.location.reload(true);
} else {
document.location.reload(true);
}
};
In chrome when i click either Ok or Cancel the confirm box just reopens instantly and it doesn't reload (Edit: Forgot to mention but the page just hangs after clicking ok) even though console logging alert it returns true. So why isn't this working on Chrome when on Firefox it's working perfectly?
I tried many different location.reload i saw when i researched on it like window.location.reload() but it's the exact same.
I'm stuck here because as i said in Firefox it works flawlessly and that's where i initially tested when i programmed the game but when i finished i decided to take a look if on Chrome it worked, that's when i found out.
Instead of location.reload() you can try (code taken from another solution online)
setTimeout(function(){
window.location.reload();
},100);
Also considering you're running the same code if alert === true and if it's not true, I would just get rid of the if/else and run the code directly (if that's what you intend to do)
document.location.reload(true); will be ok for Google chrome you can check the fiddle example here.
You have other alternatives also
setTimeout(function(){ window.location.reload(); });
window.location.reload();
A short note :
if (alert === true) {
document.location.reload(true);
} else {
document.location.reload(true);
}
Irrespective of result you are doing the same operation here, So you can simplify the code like below. The if else is not at all needed there.
document.location.reload(true);
it should be
window.location.reload(false);

jQuery Mobile 1.3 Panel Not Working After Page Change

I seem to be having issues with programmatic opening and closing of a JQM 1.3 Panel.
EDIT: This is for JQM 1.3.x not 1.4+
It is somewhat hard to explain, so I just made a fiddle :)
There is a lot going on in the fiddle, but it is just a sample of a much larger app and conveys the issue.
How to replicate:
Go to Fiddle
On Fiddle open the Panel and go to Page Two
On Page Two open Panel and go to Page One
Try to Open the Panel now on page one, it does nothing.
Browsers Affected:
EDIT: This seems to be fixed in Chrome 30.0.1599.101 m
Chrome 28.0.1500.95 m
IE 10.0.9200.16635
Safari // Latest Ver
Android WebView (4.2.2)
Browsers NOT Affected:
Firefox 23
Opera 12.16
Link to Fiddle:
http://jsfiddle.net/q2YH3/
Link to Other Posts
https://github.com/jquery/jquery-mobile/issues/6308
http://forum.jquery.com/topic/panel-not-responding-after-page-change
EDIT: So Firefox gives me an error that neither Chrome or IE do.
When I click to go back to page one, I get:
Type Error: elem is undefined
The error is thrown by JQ 1.9.1, I trace it back to this:
A method for determining if a DOM node can handle the data expando
acceptData: function( elem ) {
// Do not set data on non-element because it will not be cleared (#8335).
if ( elem.nodeType && elem.nodeType !== 1 && elem.nodeType !== 9 ) {
return false;
}
var noData = elem.nodeName && jQuery.noData[ elem.nodeName.toLowerCase() ];
// nodes accept data unless otherwise specified; rejection can be conditional
return !noData || noData !== true && elem.getAttribute("classid") === noData;
}
`
Note the :
Do not set data on non-element because it will not be cleared (#8335).
Github Issue Link:
https://github.com/jquery/jquery/pull/1232
OG Code:
$('.showMenu').on('click', function(){
$.mobile.loading('hide');
$.mobile.activePage.find('#'+$.mobile.activePage.attr('id')+'P').panel("toggle");
});
$('.btnMenuItem').on('click', function(event){
myPgActions.nav(event, function(target){
$.mobile.changePage(target);
}, false);
});
var myPgActions = {};
myPgActions = {
nav: function(event, callback, manualHash){
var PID = $.mobile.activePage.attr('id'),
target = (!!event) ? event.target.name : manualHash;
$("#"+PID+"P").panel( "close" );
if(PID != 'loading') $("#"+PID+"Iframe").hide();
if(PID == target){
$("#"+PID+"Iframe").hide('fast', function(){
$("#"+PID+"Iframe").attr('src', "");
myPgActions.update(PID, target, 'refresh', function(target){
callback(target)
});
});
}else{
this.update(PID, target, 'change', function(target){
callback(target);
});
}
},// end get
update: function(PID, target, type, updateCallback){
var ifReady = $.Deferred();
if(type == 'refresh'){
this.buildUrl(PID, function(url){
$('#'+PID+'Iframe').attr( 'src', url);
ifReady.resolve();
$.when(ifReady).then(function(){
updateCallback('#'+PID+'Iframe')
});
});
}else if(type == 'change'){
this.buildUrl(target, function(url){
$('#'+target+'Iframe').attr( 'src', url);
ifReady.resolve();
});
$.when(ifReady).then(function(){
updateCallback('#'+target);
});
}
}, // end set
buildUrl: function(page, buildCallback){
switch(page){
case 'dash':
var mobileSiteUrl = 'URL with options for iframe'
setTimeout(function(){buildCallback(mobileSiteUrl);},25);
break;
case 'local':
var mobileSiteUrl = 'URL with options for iframe'
setTimeout(function(){buildCallback(mobileSiteUrl);},25);
break;
}// End Switch
}
}// End Obj
Had the same problem, panel not showing after page changes.
Two small changes can fix that:
what I did was to change the panel from id="myPanel" to class="myPanel", then changed the call to the panel to open: $('.myPanel:visible').panel('open'); - that's it!
The problem is that the panel has to be inside of a jQuery "page", and after the transition, if you have the panel set in the target page, you actually have two (or more) panels with the same id which is wrong or same class which is fine. So you just change the id to a class and call the visible one.
Took me too long, Hope it saves time to someone else.
I played around with your code a bit. I noticed that If I put an alert inside your update function, that it fixes everything. So I researched why an alert would make a program work, and found this page.
http://ubuntuforums.org/archive/index.php/t-930002.html
"You should probably know that JavaScript evaluation is of the 'look ahead' type: the script already runs when it is still being evaluated (and while the page itself is still being evaluated). Now that is why it is recommended to dump all references to scripts in the section of your page, as it will cause the JavaScript to be fully evaluated before you (usually) can call a function (event handlers), and hence avoid silly 'undefined' errors.
Now the alert(); call has 2 effects: (1) it pops up the message box (so far, so good);.but (2) it halts the thread the JavaScript is using! However the browser's other threads will still continue to go on (HTML rendering...). So it may be one of those cases that you would benefit from a more elegant halting method, which is to only execute this (part of the) script when the document has been fully loaded;"
The solution they suggest is putting your script inside of the . Or using "stateChanged() function of the ajax http request".
Well I upvoted #A.sharif 's post, as he got the gears in my head spinning.
The problem lies in the fact that the callback of the "BuildUrl" function was executing before the URL variable was built.
I thought I had allowed ample time with 25ms but it was not. I bumped the time before the callback is executed up to 600 ms and it works fine now.
I am sure there is a more elegant solution, but this is what I got ;)
New Fiddle:
http://jsfiddle.net/t8zyQ/
What was changed was the value of 25 in the setTimeout() to 600.
Changed Code:
buildUrl: function(page, buildCallback){
switch(page){
case 'dash':
var mobileSiteUrl = 'URL with options for iframe'
setTimeout(function(){buildCallback(mobileSiteUrl);},600);
break;
case 'local':
var mobileSiteUrl = 'URL with options for iframe'
setTimeout(function(){buildCallback(mobileSiteUrl);},600);
break;
}// End Switch

document.getElementById does not return null, but also does not do what I want. No error in javascript console

In this instance, I load a single paypal page, in which I am prompted to login. Once I login, the page changes, through the use of other javascripts on paypal's end. The address does not change on this transition, nor does the source code in any material way. I am trying to find a way to have my script wait long enough after the first click to be able to get the element that loads after. I thought I could do this fairly simple using the following:
document.getElementById("submitLogin").click();
window.onload = function() {
document.getElementById("continue").click();
};
When the script is executed, the first button is clicked, the page transitions, but it won't click the second button that loads. My javascript console does not report any errors, suggesting that it is able to "get" the element. Not sure why it won't click it though.
If nothing else, you could always poll for the existence of the "continue" element at some interval:
function clickContinue() {
var button = document.getElementById("continue");
return button ? button.click() : setTimeout(clickContinue, 100);
}
document.getElementById("submitLogin").click();
clickContinue();
If you go this route, you'll probably want to include a failsafe so it doesn't run too long, in case something unexpected happens. Something like this should work:
clickContinue.interval = 100; // Look for "continue" button every 0.1 second
clickContinue.ttl = 10000; // Approximate time to live: 10 seconds ~ 10,000 ms
clickContinue.tries = clickContinue.ttl / clickContinue.interval | 0;
function clickContinue() {
var button = document.getElementById("continue"),
interval = clickContinue.interval;
return button ? button.click() :
clickContinue.tries-- && setTimeout(clickContinue, interval);
}
// ...
Take a look at PayPal's API docs and see if they provide a way to set up a callback to handle this, though. This polling technique should probably only be used as a last resort.

How to disable "prevent this page from creating additional dialogs"?

I'm developing a web app that utilises JavaScript alert() and confirm() dialogue boxes.
How can I stop Chrome from showing this checkbox?
Is there a setting I can modify?
I know I could modify the source code, but I'd like it so that Chrome could still auto-update.
I don't need to worry about other browsers since the app only runs in Chrome.
I have admin access to the (Windows) machines that run the app.
You can't. It's a browser feature there to prevent sites from showing hundreds of alerts to prevent you from leaving.
You can, however, look into modal popups like jQuery UI Dialog. These are javascript alert boxes that show a custom dialog. They don't use the default alert() function and therefore, bypass the issue you're running into completely.
I've found that an apps that has a lot of message boxes and confirms has a much better user experience if you use custom dialogs instead of the default alerts and confirms.
This is what I ended up doing, since we have a web app that has multiple users that are not under our control...(#DannyBeckett I know this isn't an exact answer to your question, but the people that are looking at your question might be helped by this.) You can at least detect if they are not seeing the dialogs. There are few things you most likely want to change like the time to display, or what you are actually displaying. Remember this will only notify the user that they are have managed to click that little checkbox.
window.nativeAlert = window.alert;
window.alert = function (message) {
var timeBefore = new Date();
var confirmBool = nativeAlert(message);
var timeAfter = new Date();
if ((timeAfter - timeBefore) < 350) {
MySpecialDialog("You have alerts turned off");
}
}
window.nativeConfirm = window.confirm;
window.confirm = function (message) {
var timeBefore = new Date();
var confirmBool = nativeConfirm(message);
var timeAfter = new Date();
if ((timeAfter - timeBefore) < 350) {
MySpecialDialog("You have confirms turned off");
}
return confirmBool;
}
Obviously I have set the time to 3.5 milliseconds. But after some testing we were only able to click or close the dialogs in about 5 milliseconds plus.
I know everybody is ethically against this, but I understand there are reasons of practical joking where this is desired. I think Chrome took a solid stance on this by enforcing a mandatory one second separation time between alert messages. This gives the visitor just enough time to close the page or refresh if they're stuck on an annoying prank site.
So to answer your question, it's all a matter of timing. If you alert more than once per second, Chrome will create that checkbox. Here's a simple example of a workaround:
var countdown = 99;
function annoy(){
if(countdown>0){
alert(countdown+" bottles of beer on the wall, "+countdown+" bottles of beer! Take one down, pass it around, "+(countdown-1)+" bottles of beer on the wall!");
countdown--;
// Time must always be 1000 milliseconds, 999 or less causes the checkbox to appear
setTimeout(function(){
annoy();
}, 1000);
}
}
// Don't alert right away or Chrome will catch you
setTimeout(function(){
annoy();
}, 1000);
You should better use jquery-confirm rather than trying to remove that checkbox.
$.confirm({
title: 'Confirm!',
content: 'Are you sure you want to refund invoice ?',
confirm: function(){
//do something
},
cancel: function(){
//do something
}
});
You should let the user do that if they want (and you can't stop them anyway).
Your problem is that you need to know that they have and then assume that they mean OK, not cancel. Replace confirm(x) with myConfirm(x):
function myConfirm(message) {
var start = Number(new Date());
var result = confirm(message);
var end = Number(new Date());
return (end<(start+10)||result==true);
}
function alertWithoutNotice(message){
setTimeout(function(){
alert(message);
}, 1000);
}

Categories