3

I am currently using the javascript setTimeout function to continuously loop through the same 4 different websites every 10 seconds. I need an accurate way to show a countdown timer of how many seconds are left before the next website is displayed. Is there a way to subtract the time being used in the setTimeout function already being used to create the timer? Here is the current Javascript that I am using:

<script type="text/javascript">
var pages = [
'webpage 1',
'webpage 2',
'webpage 3',
'webpage 4'
], p = pages.length;
while(--p > -1){
(function(p){
    var a = document.createElement('a');
    a.href = pages[p];
    pages[p] = a;
})(p);
}
function loadIframe() {
var page = pages[(p = ++p % pages.length)], bust = 'bustcache=' + new 
Date().getTime();
page = page.search? page.href + '&' + bust : page.href + '?' + bust;
document.getElementById('if_one').src = page;
setTimeout(loadIframe, 10000);
}
loadIframe();
</script>

2 Answers2

5

While you can't see it directly from setTimeout(), it's easy enough to just record the start time and do a little math:

const delay = 10000;
const start = Date.now(); // milliseconds
setTimeout(doSomething, delay);

// when needed
const elapsed = Date.now() - start;
const remaining = delay - elapsed; // divide by 1000 for seconds
samanime
  • 25,408
  • 15
  • 90
  • 139
  • I can't seem to get this to work. This is the JavaScript right? What would the HTML element look like? – Dustin Vondross Jun 20 '17 at 12:54
  • You would just periodically call `setInterval()` or any of a number of other methods and then just set the text of a `
    ` or something. There are lots of different ways to go about it. The value of `remaining` is just a number for us elsewhere.
    – samanime Jun 20 '17 at 18:45
  • Not having any luck, is this how I would call it?
    – Dustin Vondross Jun 20 '17 at 21:05
0

Yes, here is what I came up with.

var pages = [
  'webpage 1',
  'webpage 2',
  'webpage 3',
  'webpage 4'
];
var seconds = 10;
var pageIndex = 0;
var el = document.querySelector('p');
var div = document.querySelector('div');
render(seconds, pageIndex);

setInterval(function() {
  seconds--;
  if (seconds === 0) {
    seconds = 10;
    pageIndex++;
    if (pageIndex > pages.length-1) { pageIndex=0 }
  }
  render(seconds, pageIndex);
}, 1000);

function render(sec, pIndex) {
  el.textContent = sec + ' seconds remain...';
  div.textContent = pages[pIndex];
}
<h1>Count down</h1>

<p>Please wait...</p>
<div style="border: 1px solid #ccc; padding:20px">Page</div>

I used setInterval so that the timer is always counting down by decrementing seconds variable and rendering to every second.

If the 10 second interval has reached 0, we reset the timer back to 10 and increment the page index.

You can imagine the pages array actually has page1.html or whatever the URL is to load and the render function could set the iframe.src to that url.

styfle
  • 22,361
  • 27
  • 86
  • 128
  • The timer works great but it stops at 0. Is it possible to get it to refresh and countdown from 10 to 0 again at the same speed as the webpages are changing? – Dustin Vondross Jun 20 '17 at 12:45
  • @DustinVondross I updated my answer. Please consider upvoting or accepting as the correct answer if this answers your question. – styfle Jun 20 '17 at 13:19
  • I had to go back to the setTimeout for the webpage looping because I need it to continuously loop between the four webpages. When I use the setTimeout for the webpage looping and your setInterval for the timer it is almost spot on but after about an hour or so it is a second off. Imagine this time would continue to grow. – Dustin Vondross Jun 20 '17 at 14:35
  • `setTimeout` is not meant for accuracy. See [this question](https://stackoverflow.com/q/196027/266535) for some ideas on how to implement for accuracy. – styfle Jun 20 '17 at 14:38
  • Thanks, I didn't see an example though? – Dustin Vondross Jun 20 '17 at 16:41
  • I don't need to use setTimeout if I don't have to, just haven't found a way to continuously loop between the different websites. Any suggestions? – Dustin Vondross Jun 20 '17 at 20:56