1

This may be a quite naive question but I really need some help.

Prior to writing this post, I was programming on JSBin. Turns out without me realizing, I ran a setInterval loop prompting for userInput and it kept on looping, making me unable to click anywhere to change the code to fix the loop. It kept on repeating and repeating. It got to the point where I had to refresh and lose all my hard-written-code (I was not logged in, so my code was not saved)! I want to avoid that next time.

So, my question is how do I stop any such kind of setInterval Loops, so that I am able to access my code and change it and re-run it. Below is a code that demonstrates my issue, if you try running it on JSBin.com (obviously, it is not the code I wrote before). As you can see, I can not click on my code to change it (or save it) in any way, which means I lose all my code!

This may seem like a useless question, but I really want to know ways to fix it and perhaps fixing it from the developer tools will help me be familiar with the overwhelming set of tools it has :P. So please help me if you know a solution.

Thank you for taking your time to help me! I appreciate it.

setInterval(demo,1);
function demo()
{
     var name = prompt("Enter your name: ");
}
Yogesh
  • 13
  • 2

3 Answers3

1

That's kind of a hack and should only be used in cases like the one exposed in OP but,
About all implementations use integers as timerid that just get incremented at every call.

So what you can do, is to clear all timeouts that were created on the page.
To do so you need to first get to which timerid we are, then call cleatTimeout or clearInterval (they do the same) in a loop until you reach the last call:

function stopAllTimers() {
  const timerid = setTimeout(_=>{}); // first grab the current id
  let i=0;
  while(i < timerid) {
    clearTimeout(i); // clear all
    i++;
  }
};
btn.onclick = stopAllTimers;

// some stoopid orphan intervals
setInterval(()=>console.log('5000'), 5000);
setInterval(()=>console.log('1000'), 1000);
setInterval(()=>console.log('3000'), 3000);
const recursive = () => {
  console.log('recursive timeout');
  setTimeout(recursive, 5000);
};
recursive();
<button id="btn">stop all timeouts</button>
Kaiido
  • 123,334
  • 13
  • 219
  • 285
  • Even if he did preemptively add this to every bin he creates, he still won't be able to click the button in the case of an endless modal – Leroy Stav Jan 16 '19 at 04:11
  • 1
    With what OP's encountering (such as with JSBin or JSFiddle or stack snippets), they'll have to access the *sandboxed iframe*'s `.contentWindow.setTimeout` (otherwise they'll just be accessing the non-sandboxed page window, which is unresponsive due to the iframe and doesn't have problematic timeouts running) – CertainPerformance Jan 16 '19 at 04:12
  • Yes that's a good point @CertainPerformance still very doable though. Most dev-tools consoles have a switch context option. – Kaiido Jan 16 '19 at 04:13
  • @LeroyStav you would run this from the console ;-) – Kaiido Jan 16 '19 at 04:14
  • @Kaiido I learned something new today! f12 works in chrome even when a modal is open! Thanks :-) I mean, not that I would ever ever need to know this... I can't remember the last time I used `alert` or `prompt` – Leroy Stav Jan 16 '19 at 04:16
  • And actually with OP's case, just removing the iframe from the DOM should do. – Kaiido Jan 16 '19 at 04:17
  • @Kaiido I am quite a beginner when it comes to javascript, so I am not sure I understand. I did run your code, which works with them looping in the console, however not with prompt() which does not allow me to click on the button at all (I can press ok or nothing!). – Yogesh Jan 18 '19 at 00:38
  • As mentionned in previous comments, you'd need to run this code from the iframe's context. You can switch your console context in Chrome thanks to the dropdown menu at top left of the console area ( should default to "top"), set it to the one of the inner iframe – Kaiido Jan 18 '19 at 00:43
1

Assuming the dev tools are closed, hit esc and f12 nearly simultaneously. This should open the dev tools. If it doesn't keep trying until it does.

Once they are open, hit esc and f8. Again, retry til it halts javascript execution at some arbitrary point in the code.

In the "sources" tab locate the generated script for what you wrote (offhand I don't know how it would look like from within JSBin) and literally delete the var name = prompt("Enter your name: "); line. Hitting f8 again will continue execution as if the "new" code is running. This should free you up to copy/paste your code from the site itself before you refresh the page

Leroy Stav
  • 722
  • 4
  • 12
  • of course this is specifically for when an alert/prompt is blocking you from access to the page itself. otherwise, simply hit `f12` to open the dev tools and `f8` to halt execution – Leroy Stav Jan 16 '19 at 04:11
  • I found the code under: (runner)/ JS Bin Output / (no domain) / *(someweirdname).js file. Yes, it was very helpful in that it would allow me to copy my code. However, it didn't run as "new"; after I deleted that line and even the setInterval line it still ran the same code. Thank You for the solution though! – Yogesh Jan 18 '19 at 00:55
  • Thank you'd are great, but accepting answers is better! – Leroy Stav Jan 18 '19 at 01:44
  • Really, @HavocLee? Be considerate to the people who help you and *mark answers as correct* if they help! We take the time to help you out, the least you can do is click a button. – Leroy Stav Jan 24 '19 at 06:20
  • I actually did. Yours was obviously helpful but I can only mark one answer :( - so I chose the one I thought was the most helpful. – Yogesh Jan 31 '19 at 01:02
1

Another option is to search the developer tools "Elements" panel for the iframe (this should be doable even if the main document is unresponsive due to prompt's blocking) - then, just right click the iframe element and remove it, no need to type any Javascript. (or, if you want you can select the iframe with querySelector and remove it, eg document.querySelector('iframe').remove())

CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
  • @CertainPerformace Wow! That worked wonders. Thank you! Funny though when I tried expanding all the options and looking for iframe tag I could not find it. Guess it does not show the full file? – Yogesh Jan 18 '19 at 01:03
  • Try using control-F and type in `iframe`, and it should expand to the iframe eventually, after clicking through some of the prompts (may not respond until a prompt is submitted, unfortunately). Or, open the page in a separate tab and check where the iframe is located in the HTML, then navigate to that position on the blocked page. – CertainPerformance Jan 18 '19 at 01:08