4

Existing code

I use the following code in ViolentMonkey (or GreaseKit or TamperMonkey) to refresh a page every 30 seconds:

setTimeout(function(){ location.reload(); }, 30*1000);

Can I make it stop?

This has been working fine for many years. But now, I want my code to NOT refresh the page if the following phrase is present: Important shizzle

(The reason I don't want it to refresh under this condition is because then I will no longer be able to see what was written.)

I am unenlightened

I know almost no Javascript. I've watched tutorials on YouTube, to try and learn the basics. I often google small questions and find answers on Stackoverflow (thanks all) - but I'm still very slow


Strategy thoughts

  1. Search for the phrase Important shizzle - if it exists then end the script.
  2. Then I'd just have my existing code: setTimeout(function(){ location.reload(); }, 30*1000);

Alas I cannot find an elegant Javascript command to abruptly end the script.

Would this work?

if( !document.body.textContent.includes("Important shizzle")) location.reload();

The problem is that the above doesn't do it every 30 seconds, it just does it once

3 Answers3

3

You can read the .innerText property of the body, then use String#includes to see if your phrase is present.

If it is present you can return out of the function to end the script.

Something like this:

const timeout = setTimeout(function () {
  if (document.body.innerText.includes('Important shizzle')) return;
  location.reload();
}, 30 * 1000);
lejlun
  • 4,140
  • 2
  • 15
  • 31
  • 1
    Thank you so much for your thoughtful answer! I am now reading the about innerText, includes and return – Nicholas Kunze Aug 28 '21 at 21:43
  • I had read that `return` was not suitable for ending a script, on a stackoverflow answer, so I had ruled out using it: https://stackoverflow.com/questions/550574/how-to-terminate-the-script-in-javascript – Nicholas Kunze Aug 28 '21 at 22:18
  • i have read up on innerText, very interesting. The page i am working on has a very simple document structure; so i don't need anything that fancy, but it's so cool that it exists! – Nicholas Kunze Aug 28 '21 at 22:36
  • @NicholasKunze if it solved your issue, then you should mark it as Accepted Answer, all users can do this. – KeitelDOG Aug 28 '21 at 23:54
  • 2
    I have tested this one and it definitely works! – Nicholas Kunze Aug 29 '21 at 15:31
2

You can do it this way :

setInterval(reload, 30*1000);

function reload() {
    if ( isReloadOK() ) location.reload();
}

function isReloadOK(){
    if (document.body.textContent.includes("Important shizzle")) return false;
    return true;
}
learner
  • 341
  • 2
  • 11
  • Thanks very much for your considered response. I'm reading up on `setInterval` now. Of the three answers, yours is the easiest to read and understand (to me, a newbie) – Nicholas Kunze Aug 28 '21 at 22:32
  • `setInterval` can be replaced by `setTimeout` since it will perform a reload, it won't be able to repeat interval multiple time anyway. – KeitelDOG Aug 28 '21 at 23:56
  • @KeitelDOG If Nicolas wants to checks every 30s if the page should be reloaded, then setInterval is necessary. If he only wants to checks if the page should be reloaded 30s after the the page loaded, then indeed setTimeout is enough (It's not clear to me what he wants to achieve). Nicolas, if you use my answer, you can mark it as the Accepted Answer :). – learner Aug 29 '21 at 06:45
  • @learner I agree. From what the OP said, he wants to check if the page should be reloaded after 30 seconds. However, if the OP doesn't really know the HTML-JS stack, then he might as well need to do it every 30 seconds, and when condition is met, to reload it. This would have him to know where the phrase is coming from, direct Page HTML Response, or Client Ajax Responses from the App that he uses. – KeitelDOG Aug 29 '21 at 14:32
  • What happens when there are two answers that appear to solve the problem? I am still testing so I can't yet confirm - but I suspect that yours and @lejlun's will work – Nicholas Kunze Aug 29 '21 at 14:49
  • @KeitelDOG in my case, the `Important shizzle` appears at the moment the page is rendered (not 1-29 seconds later) (it's a very simple page) – Nicholas Kunze Aug 29 '21 at 14:50
  • @KeitelDOG ACTUALLY, it may be generated a second or so after reload! I can't tell as it happens so fast! It's an interesting distinction that I hadn't even thought of! – Nicholas Kunze Aug 29 '21 at 15:04
  • I have just tested this and can confirm at *also works*! An aside: i wonder why this answer has the includes thing in `"` whereas the other answer uses `'` ? – Nicholas Kunze Aug 29 '21 at 15:43
1

You can have the timeout and you can ADD an interval and I will use the example from what you have shown already.. the most important part is clearTimeout

var timeout=setTimeout(function(){ location.reload(); }, 30*1000);
var interval=setInterval(()=>{
  let condition = document.body.textContent.includes("Important shizzle");
  if(condition){clearTimeout(timeout); clearInterval(interval)}
},0);
The Bomb Squad
  • 4,192
  • 1
  • 9
  • 17
  • Meanwhile in your code, `setInterval` will execute instantly because the 2nd parameter (time) is required to wait. But since it's combine with `setTimeout`, it should do it, though very complex for the OP to even understand what's going on. And for a page that reloads, `setInterval` that executes infinitely is identical with `setTimeout` that executes only once. An edge case this could not find the phrase, is that if the App wait a few time to display the Phrase, because the OP don't really know how the Phrase get there (HTML response, Ajax Client request, etc.). – KeitelDOG Aug 29 '21 at 14:24
  • Thank you very much for your thoughtful answer. I am going to now watch some tutorials about `clearTimeout` since this is new to me – Nicholas Kunze Aug 29 '21 at 14:54
  • Ah, i have only just seen @KeitelDOG's comment of 29 mins ago. It is indeed very complex to me! – Nicholas Kunze Aug 29 '21 at 14:56
  • @KeitelDOG the interval is for the timeout to clear at any point in time when the condition is met(since that condition can occur at any time).. also I changed my answer so that the interval would *also* be cleared when the good condition is met – The Bomb Squad Aug 30 '21 at 11:20
  • @TheBombSquad what I meant is that, `setInterval` call is not necessary because it launches instantly, it's like executing its internal code directly, without wrapping them in the `setInterval`. And most of all, it will execute that code infinitely and could cause harm to the browser tab at a certain point. Clearing the Interval will prevent it from executing infinitely, but still it will execute the codes inside instantly, so that you don't even have to use setInterval at all. – KeitelDOG Aug 30 '21 at 16:49