JS and HTML5: Countdown Bar only works "on screen"

Asked

Viewed 203 times

0

I’m implementing a small progress bar (.progressbar) that actually works as a "countdown bar" (it’s an inverted progress bar, it starts full and goes down) and will work as a session expiration control (at the end of the time - JS does the page re-load and as the session will be expired it is blocked)

the session control is working OK - which is the most important - but a problem has disturbed me - the animation of the bar is not correctly following the time - IF THE USER DOES NOT STAY ON THE SCREEN (q is one of the reasons to implement this - if the user "forget the open window" - the system takes care to close it alone so as not to expose the data - even if another user does not have to "access" the system since the session has already crashed - he would still have time to "see the exposed data" - until the timer completes.

would be some problem in the code or is something from the browser (I have not yet made larger tests - I just implemented - I only used it in Chrome "last version")

Thank you!

follows the JSFIDDLE: https://jsfiddle.net/2tonbd5k/

*I did not put the page Load line there not to give the Load in jsfiddle - but in the page this ok - the question is the animation of the bar that stops when we change the page on the screen (we open see the material and we go to another tab) - the animation seems to (and while she doesn’t "Zera" she also doesn’t activate the Reload).

function progress(timeleft, timetotal, $element) {
  var progressBarWidth = timeleft * $element.width() / timetotal;
  $element.find('div').animate({
    width: progressBarWidth
  }, timeleft == timetotal ? 0 : 1000, "linear");
  if (timeleft > 0) {
    setTimeout(function() {
      progress(timeleft - 1, timetotal, $element);
    }, 1000);
  }
};

progress(25, 25, $('#progressBar'));
#progressBar {
  width: 90%;
  margin: 10px auto;
  height: 2px;
  background-color: #E0E0E0;
}

#progressBar div {
  height: 100%;
  text-align: right;
  padding: 0 0px;
  line-height: 2px;
  width: 0;
  background-color: #FF0000;
  box-sizing: border-box;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="progressBar">
  <div class="bar"></div>
</div>

  • this happens because some browsers (think q FF and IE no longer have this problem need to confirm) block setInterval when it has no focus. Note that it is not even necessarily in the window, I think only in the viewport, if you scroll and disappear the Animation it is already interrupted.

  • 1

    a simpler solution is, use as reference the time difference in place of "timeleft", this causes the return focus to be updated correctly, and even allows the timer is not necessarily linked to 1 second

  • I made that code here a version of your code but using webworker. The animation got a little rough because it’s not animated via CSS but if you’re interested I can formulate an answer explaining how it works and what principles are involved.

  • @Augustovasques thank you very much! Animation to me is good :D - the important thing is to solve.. rs - was seeing the code - I am not an expert in programming,

  • Do you want me to write a reply explaining what I did? If yes, at the moment I am writing another answer then I will take to give you a feedback.

  • 1

    hi @Augustovasques, all right, no hurry - I’m seeing if I can implement the solution given by Ricardo Pontual - it seems to be something simple (of course it is..rs) - but I’m exercising my brain a little to find out how to change timeleft for the hour.. rs

Show 1 more comment

1 answer

1


I put a numeric timer on the bar just to make it easier to check that the time is really reduced - but I will at least remove this inhibiting the line

progressBar.innerHTML = `${timeleft} seg`;

to redirect (and log off the page) - you must call the line, taking out the "/" and changing the ADDRESS to the redirect address:

// window.location.replace("ENDEREÇO");

and I will reduce the height of the bar to 2px - to be "thin" as in the original example. but the solution is this!!

const progressBar = document.querySelector('#progressBar .bar');
function progress(startTime, timetotal) {
    const timeleft = timetotal + (startTime - Date.now()) / 1000 | 0;
  if (timeleft > 0) {
    const progressBarWidth = timeleft * 100 / timetotal;
    progressBar.innerHTML = `${timeleft} seg`;
    progressBar.style.width = `${progressBarWidth}%`;
    setTimeout(progress, 1000, startTime, timetotal);
  } else {
    progressBar.innerHTML = ``;
    progressBar.style.width = "0";
    // window.location.replace("ENDEREÇO");
  }
}

progress(Date.now(), 180);
#progressBar {
  width: 90%;
  margin: 10px auto;
  height: 22px;
  background-color: #E0E0E0;
}

#progressBar div {
  transition: width 1s;
  height: 100%;
  width: 100%;
  text-align: right;
  padding: 0 0px;
  line-height: 22px; /* same as #progressBar height if we want text middle aligned */
  width: 0;
  background-color: #FF0000;
  box-sizing: border-box;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="progressBar">
  <div class="bar"></div>
</div>

Browser other questions tagged

You are not signed in. Login or sign up in order to post.