I have a simple question maybe, I was for days looking for solution and don't want to waste your time, but isn't work for me so I'm here now.
Im using P5JS, and I wanted to create auto click function.
There how I call an button in sketch.js file
var button1 = createButton("Generator");
button1.mousePressed(banana);
button1.id('autoclick');
Here you can see how I call in index.html
Im trying something like this:
<script type="text/javascript">
var iteration = true;
var time = new Date();
var delay = 5000; // 5 secondes
while(iteration) {
if(time.getTime() + 5000 < new Date().getTime()) {
iteration = false;
}
}
document.getElementByID('autoclick').click();
// noprotect
</script>
Maybe I complicate to much? any suggetions? thank you!
Your while loop is blocking, which means that while Javascript is running your while loop, it will not be able to execute any other code. You want to use setInterval() for your purposes.
For example,
setInterval(() => console.log("hello!"), 1000)
I have written the following JavaScipt code within a Spotfire TextArea. I include the application and tag for completeness, but I don't believe my issue is Spotfire-specific. Essentially, I have a timer which runs every 5 minutes, and clicks on a link (clickLink('Foo');) to trigger execution of some Python code elsewhere in the application. If the application also contains a timestamp of the last full update, which occurs every 30 minutes in the same manner (clickLink('Foo');):
function reportTimestamp() {
var timeNow = new Date();
var hoursNow = timeNow.getHours();
var minutesNow = timeNow.getMinutes();
var secondsNow = timeNow.getSeconds();
return hoursNow + ":" + minutesNow + ":" + secondsNow;
};
function timeBasedReaction(timestampAge){
if (timestampAge >= 1800) {
clickLink('Foo');
clickLink('Bar');
} else if (timestampAge >= 300) {
clickLink('Foo');
};
};
/*
function timeBasedReaction_B(timestampAge){
if (timestampAge >= 300) {
clickLink('Foo');
if (timestampAge >= 1800) {
clickLink('Bar');
};
};
};
*/
function clickLink(linkName) {
var clickTarget = document.getElementById(linkName).children[0];
clickTarget.click();
};
function checkTimestampAge() {
console.log(reportTimestamp());
var myTimeStamp = document.getElementById('Timestamp').children[0]
var timeStampMS = new Date(myTimeStamp.textContent).getTime();
var currentDateMS = new Date().getTime();
var timestampAgeSeconds = (currentDateMS - timeStampMS)/1000;
timeBasedReaction(timestampAgeSeconds);
};
function pageInitialization() {
checkTimestampAge();
var myTimer = null;
var timerInterval = 300000;
myTimer = setInterval(function(){checkTimestampAge()},timerInterval);
}
pageInitialization();
For reasons unclear to me, running this code in the application or in a web browser starts off fine, but eventually leads to very large memory allocation.
I've tried to read
4 Types of Memory Leaks in JavaScript and How to Get Rid Of Them,
JS setInterval/setTimeout Tutorial, and
An interesting kind of JavaScript memory leak, and it's a start, but I don't know enough to really understand what I'm doing wrong and how to correct it.
Thanks, and sorry for the huge block of text.
This causes a memory leak because of how Spotfire handles Javascript which has been associated with/loaded into a TextArea.
Both in the desktop client, as well as in the Webplayer instance, when the page is loaded, all the portions of that page are loaded, include the TextArea and including the Javascript associated therein. My previous understanding in the comments above:
"the code is intended to run when the page loads, and it was my understanding that it would stop/be cleared if the page was re-loaded or someone navigated away from it"
was incorrect. One of the script's actions was to update/redraw the HTML location in the TextArea. This, in turn, reloads the TextArea but does not clear the existing Javascript code. However, it's not really accessible anymore, either, since var myTimer = null actually creates a new myTimer rather than nulling-out the existing one. In this way, instances of myTimer increase geometrically as instances of function timeBasedReaction run and continually update the underlying TextArea and load in more of the same Javascript.
To anyone who ha a similar issue and come here, it's been over 3 months and I haven't figured out how to solve this once and for all. If I do, I'll try to come back with another update.
run = 0
function getLowestPrice(id){
$.get('/items/' + id + '/privatesaleslist', function(data){
var html = $(data);
var lowestPrice = parseInt($('.currency-robux', html).eq(0).text().replace(',', ''));
console.log(lowestPrice);
})
}
while (run < 100)
{
getLowestPrice(362081769);
run = run + 1
}
Webpage I am using this code on: https://m.roblox.com/items/362081769
What happens is when I run this code it runs successfully 20 times returning 3997, and then I get spammed with "NaN" Image.
What i'm trying to get this program to do is check the price of the item for as long as I want, and report it in the chrome console. Why does the function work 20 times and then just return NaN?
I am a beginner at javascript, so please explain your solutions so a beginner like me can understand.
Thanks :)
Hey man I think part of your issue is in the while loop mechanic. Whenever run hits 100 your function will stop being called.
You could use a setInterval function. How this work is it will call whichever function you pass it, every "x" milliseconds.
setInterval will call getLowestPrice with the id of 362081769, every 5 seconds.
const id = 362081769
function getLowestPrice(){
$.get('/items/' + id + '/privatesaleslist', function(data){
var html = $(data);
var lowestPrice = parseInt($('.currency-robux', html).eq(0).text().replace(',', ''));
console.log(lowestPrice);
})
}
setInterval(getLowestPrice, 5000);
Also here is a link to the formal setInterval documentation.
https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setInterval
I hope this helps :)
I am making a small userscript for a survey site. Whenever I click the survey and it is indicated that I did not receive it the script is supposed to refresh a certain amount of times trying to claim the survey until it gives up.
(If you do not know what a userscript is, think of it as something that stays running all the time on a specific website, so you can control things using javascript selectors and stuff)
This is my script so far (the javascript portion as that is what the problem is in):
var elementExists = document.getElementsByClassName("message warning")[0];
if(elementExists)
{
var attempts = 0;
while(attempts<5)
{
attempts += 1;
location.reload();
if(elementExists)
{
//nothing
}
else
{
window.stop();
}
}
window.stop();
}
This is actually my first time using Javascript so I assumed that would be the reason for errors, but after 45 minutes of debugging I am completely baffled. If I remove that last "window.stop();" the code refreshes the webpage infinitely. If that stays there then the code doesn't even start. It seems almost as if the while loop is being skipped if the "window.stop();" is present. Is this something that Javascript does, or is the problem elsewhere?
If someone could lead me in the right direction or help me fix this I would be very grateful!
(Also I checked the selector to see if that is the issue, but I have done that correctly)
UPDATE: Turns out location.reload(); stops the script and thus forces a reload. Since I am creating a userscript I realized that I could use the Greasemonkey APIs (or more like stumbled upon). By using GM_setValue and GM_getValue I was able to work around this problem and the script successfully reloaded a certain amount of times (depending on the variable tries) and stopped when it finished. But after messing around a bit, then reverting to the older version the script, the script doesn't doesn't execute at all anymore; "counter < tries" seems to be false for some reason... could anyone figure out why? Also if documentation is needed:
https://wiki.greasespot.net/GM_getValue
https://wiki.greasespot.net/GM_setValue
var tries = 5;
var elementExists = document.getElementsByClassName("message warning")[0];
var counter = GM_getValue('counter', 0);
if(elementExists && counter < tries)
{
GM_setValue('counter', ++counter);
location.reload();
}
(Both counter and tries seem to be integer values.. so there should be in problem in comparing them...)
Also as suggested by #yuriy636 I attempted to reset the variables and created something like this
var tries = 5;
var elementExists = document.getElementsByClassName("message warning")[0];
var counter1 = GM_getValue('counter1', 0);
if(elementExists && counter1 < tries)
{
GM_setValue('counter1', ++counter1);
location.reload();
}
if(elementExists && counter1 == tries)
{
GM_deleteValue('counter1');
window.close();
}
if(!!elementExists)
{
GM_deleteValue('counter1');
return;
alert("stops script while hidden");
}
But again I am hit with the infinite loop.. RIP
Update 2: Not so RIP afterall... solution:
var tries = 50;
var elementExists = document.getElementsByClassName("message warning")[0];
var counter = GM_getValue('counter', 0);
if(elementExists && counter < tries)
{
GM_setValue("counter", counter + 1);
location.reload();
}
else
{
GM_deleteValue("counter");
}
if(elementExists && counter >= tries)
{
window.close();
}
100% Working, after indicated amount of tries, if error still exists the page is closed
The most likely problem is that you have location.reload() in your while loop. This causes the page to refresh before anything interesting happens in your loop. In this particular code I would expect the page to refresh seemingly infinitely because every time the page refreshes, it will refresh again.
Normally this would look more like:
var elements = document.getElementsByClassName("message warning");
for (var i = 0; i < elements.length; i++) {
console.log (elements[i]);
}
.getElementsByClassName returns an array of elements with the class message and/or warning which you are capturing only the 1st one [0]. Hope that helps.
I have a browser-based application that I use at work (as effectively all corporate apps are now browser-based for obvious reasons) that has an annoyingly short session timeout. I'm not sure precisely what the session timeout is set to, but it's something along the order of 5-10 minutes.
Inevitably whenever I have to use it the session has timed out, I enter the information into the app, submit it, and then the page loads with a brand new session without any of the information actually being passed on - all I get is a new session. I then have to re-enter the information and submit it again in order to have it actually pull up what I want. Of course, I could first refresh the page and then enter the info, but I never know if the session is timed out or not and occasionally it runs painfully slowly so this is a waste of time. Our development team's inability to foresee that little things like this are not only annoying, but also end up costing us a ton of money when you consider the amount of time lost (I work for a VERY large corporation) just waiting for the blasted thing to reload and then having to re-enter the submitted information if a pre-refresh was forgotten as it usually is happens to be beyond me. At some point I'm hoping to become the liaison between the programmers and our customer service body.
Anyway, I digress.
What I'm looking to do is this: I'd like to create a Javascript bookmarklet or something that will automatically refresh whatever page it happens to be on if activity isn't detected within a certain timeframe. This timeframe will be a bit short of whatever I end up figuring out what the session timeout is. Basically I just want to make the page reload itself every, say, five minutes if there hasn't been activity within that period. (I don't want it to refresh out of the blue because the time is up while I'm in the middle of using the app, the only time it should do the auto-refresh is if the app page has been sitting idle)
Can this be done with a Javascript bookmarklet? Should I program a page "wrapper" of sorts that loads the application page within an iFrame or something of the sort? The app site that I use has many subpages, and I'd prefer for it to refresh whatever page I happen to be on at the time if the auto-refresh timeout occurs. Of course, if that isn't possible I'd accept it just reloading the main site page if that's not easily possible since if I've been out of the app long enough for the timeout to happen then I likely don't need to still be on whatever account/page I was on at the time.
Hopefully I've explained myself well enough. The logic is simple - if no activity detected withing x amount of time, refresh the current page is the gist of it.
Thank you, my StackOverflow brethren, yet again for your assistance.
-Sootah
Since I have no ability to influence the coding of the page itself, I've got to have the most simple solution possible. A bookmarklet that times the last refresh/pageload and then refreshes the same page if the timeout is reached would be perfect.
If that's not possible, then if I could write a simple page that I could run from the local computer that'd do the same function by loading the page in a frame or something that'd also be acceptable.
EDIT 10/3/11 7:25am MST
Since I work graves and an odd schedule at work (and this site, unfortunately, being blocked there since it's considered a 'forum' - I work in finance, they're overly cautious about information leakage) before I award the bounty, does one of these event detectors detect the last time the page loaded/? Something like document.onload or whatnot. I'm thinking that setting the timer from the last time the page was loaded is going to be the simplest and most effective approach. My mouse may move over the browser that I have the site open in inadvertently while working on other things, and if the timer resets because of that without me actually having interacted with the site in such a way that a page loads/reloads then the session times out.
This is the bookmarklet code #1 for you, set up to FIVE seconds. Change time to what you like more.
javascript:
(function () {
var q = null;
function refresh() { window.location.reload(); }
function x() { clearTimeout(q); a(); }
function a() { q = setTimeout( refresh, 5000 ); }
document.body.onclick = x;
document.body.onmousemove = x;
document.body.onmousedown = x;
document.body.onkeydown = x;
}())
p.s.: would have been nicer to include eventListeners, but i suppose you need to support IE8, too, so i replaced them with inline events, - if you DON'T need IE8, use code #2:
javascript:
(function () {
var q = null;
function refresh() { window.location.reload(); }
function x() { clearTimeout(q); a(); }
function a() { q = setTimeout( refresh, 5000 ); }
document.body.addEventListener( "click", x, false );
document.body.addEventListener( "mousemove", x, false );
document.body.addEventListener( "mousedown", x, false );
document.body.addEventListener( "keydown", x, false );
}())
edit: in response to comments, here is code #3 with pulling, instead of refreshing page. Yet, despite advices to use iframe, i decided it might be desirable to not execute scripts on that page, so we will use img instead:
javascript:
(function () {
var q = null;
var u = window.location.href;
var i = document.createElement('img');
i.style = "width: 1px; height: 1px;";
document.body.appendChild(i);
function refresh() {
i.src = "";
i.src = u;
x();
}
function x() { clearTimeout(q); a(); }
function a() { q = setTimeout( refresh, 5000 ); }
var evs = ['click', 'mousemove', 'mousedown', 'keydown'];
for( var j = 0; j < evs.length; j++) {
document.body['on'+evs[j]] = x;
}
}())
Create a bookmark and place the code below in the "url" value. Please note that you should change the values of "sessiontimeout" and "checkinterval". They're both in milliseconds.
javascript:(function(){var lastmove = new Date().valueOf(),sessiontimeout=10000,checkinterval=1000;document.onmousemove = function(e){lastmove= new Date().valueOf();};timer = setInterval( function() {var differential = (new Date().valueOf() - lastmove);if (differential > sessiontimeout) {var iframe = document.getElementById("bkmrkiframerefresher");if (iframe) { document.getElementsByTagName("body")[0].removeChild(iframe);} iframe = document.createElement("iframe");iframe.setAttribute("src", "/");iframe.setAttribute("width", 0);iframe.setAttribute("height", 0);iframe.setAttribute("style", "width:0;height:0;display:none;");iframe.setAttribute("id", "bkmrkiframerefresher");document.getElementsByTagName("body")[0].appendChild(iframe);lastmove = new Date().valueOf();} }, checkinterval);})();
This is a bookmarklet that will inject the code below in the page. I tested the bookmarklet in Chrome. It worked on multiple sites except stackoverflow, it seems that they block framing for security reasons. Before you leave your desk, open the website which session you wanna keep alive, then click the bookmarklet on it. Once you're back, refresh the page in order to get rid of the running timers.
The formatted (and commented) code is:
<script type="text/javascript">
// last time the mouse moved
var lastmove = new Date().valueOf();
var sessiontimeout=10000;
var checkinterval=1000;
// reset the last time the mouse moved
document.onmousemove = function(e){
lastmove= new Date().valueOf();
}
// check periodically for timeout
timer = setInterval( function() {
var differential = (new Date().valueOf() - lastmove);
if (differential > sessiontimeout) {
var iframe = document.getElementById("bkmrkiframerefresher");
// iframe already exists, remove it before loading it back
if (iframe) {
document.getElementsByTagName("body")[0].removeChild(iframe);
}
// alert("more than 10 secs elapsed " + differential);
// create an iframe and set its src to the website's root
iframe = document.createElement("iframe");
iframe.setAttribute("src", "/");
iframe.setAttribute("width", 0);
iframe.setAttribute("height", 0);
iframe.setAttribute("id", "bkmrkiframerefresher");
iframe.setAttribute("style", "width:0;height:0;display:none;");
document.getElementsByTagName("body")[0].appendChild(iframe);
// reset counter.
lastmove = new Date().valueOf();
}
}, checkinterval);
</script>
Stefan suggested above that you need no logic besides polling. The edited code is the following:
<script type="text/javascript">
var pollInterval=1000;
timer = setInterval( function() {
var iframe = document.getElementById("bkmrkiframerefresher");
// iframe already exists, remove it before loading it back
if (iframe) {
document.getElementsByTagName("body")[0].removeChild(iframe);
}
// create an iframe and set its src to the website's root
iframe = document.createElement("iframe");
iframe.setAttribute("src", "/");
iframe.setAttribute("width", 0);
iframe.setAttribute("height", 0);
iframe.setAttribute("id", "bkmrkiframerefresher");
iframe.setAttribute("style", "width:0;height:0;display:none;");
document.getElementsByTagName("body")[0].appendChild(iframe);
}
}, pollInterval);
</script>
This code only reload the page once
Here is a bookmarklet(inspired by Kaj Toet's pseudo code), tested in Chrome and Safari, change the timeout value with the var time at the start of the line
Onliner:
javascript:var time = 500; var timeoutFunc = function(){location.reload(true);};timeout = setTimeout(timeoutFunc,time);document.onmousemove = function() {clearTimeout(timeout);timeout = setTimeout(timeoutFunc,time); };
Code
//The time in milliseconds before reload
var time = 500;
//The function that is called when the timer has reached 0
var timeoutFunc = function() {
location.reload(true);
};
//start the timer
timeout = setTimeout(timeoutFunc,time);
//restart the timer if the mouse is moved
document.onmousemove = function() {
clearTimeout(timeout);
timeout = setTimeout(timeoutFunc,time);
};
pseudocode
timeout = settimeout("call",200);
document.onmousemove = function() { timeout = new timeout("call",200); }
function call() {
document.refresh();
}
like this?