3

I have a countdown timer, in the style of a bar, that slowly decreases in width.

Check the following code:

HTML

<div id="timer"><span></span></div>

CSS

#timer {
    height: 30px;
    display: block;
    overflow: hidden;
    background: grey;
}

#timer span {
    width: 100%;
    height: 100%;
    display: block;
    background: green;
    -webkit-animation-name: decreasewidth;
    animation-name: decreasewidth;
    -webkit-animation-iteration-count: 1;
    animation-iteration-count: 1;
    -webkit-animation-timing-function: linear;
    animation-timing-function: linear;
    -webkit-animation-fill-mode: forwards;
    animation-fill-mode: forwards;
    -webkit-animation-duration: 20000ms;
    animation-duration: 20000ms;
}

@keyframes decreasewidth {
    to { width: 0% }
}

@-webkit-keyframes decreasewidth {
    to { width: 0% }
}

Sadly, the animation will halt when the page isn't in use, eg. browsing another tab or window. I understand this is ordinary among browsers and helps save processing power.

Problem is, I want my timer to be accurate. That means holding true to its position even when the user flicks to other tabs during. How would I go about achieving this?

At first, my thoughts were along the lines of calculating the amount of ms the user was absent from the page and then updating the timer's span accordingly on return. But this would only happen on the focus event, which relies on user activity.

I also tried a good ol' javascript setInterval technique which simply updated the width of the span every second. Not only did this look terrible - the same problem occurred. Most browsers increase the interval time when inactive.

Interested to hear some ideas on how to handle this.

TL;DR

I need an animated countdown timer bar, that keeps true to its position even when the page is inactive.

EDIT

I know this is noticeable in Safari.

Luka
  • 603
  • 6
  • 12
  • Store the time in a cookie or local storage when the tab is not active, and then once they click back into it, load the value from the save. – Waxi Mar 10 '17 at 20:11
  • 1
    Have you stumped upon this identical question? http://stackoverflow.com/questions/5927284/how-can-i-make-setinterval-also-work-when-a-tab-is-inactive-in-chrome – Roko C. Buljan Mar 10 '17 at 20:13

2 Answers2

1

How about using standard CSS transitions and one line of jQuery?

You can start the loading bar at 100%, with a width transition of 20 seconds. Then, when the page is loaded, add a class that overrides the width and sets it to 0. Because of our transition, it will decrease from 100% to 0% over the course of 20 seconds.

Here's a JSFiddle.

$(document).ready(function() {
    setTimeout(function() {$("#timer span").addClass("load");}, 1);
});
#timer {
    height: 30px;
    display: block;
    overflow: hidden;
    background: grey;
}

#timer span {
    height: 100%;
    display: block;
    background: green;
    transition: 20s width linear;
    width: 100%;
}

#timer span.load{
        width: 0%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="timer"><span class="init"></span></div>
Tyler Roper
  • 21,445
  • 6
  • 33
  • 56
  • BTW, Chrome seems to be less harsh. Safari will completely stop the animation when window not focused. – Luka Mar 10 '17 at 20:18
  • Is this solution behaving that way in Safari? – Tyler Roper Mar 10 '17 at 20:22
  • Yes, try http://codepen.io/anon/pen/OppqOY in Safari. – Luka Mar 10 '17 at 20:27
  • Unfortunately I can't. I'm on Windows, Safari was discontinued years ago. – Tyler Roper Mar 10 '17 at 20:28
  • 1
    I don't think introducing jquery is helpful. The OP is asking about CSS. I have a similar situation and jquery isn't an option. – loctrice Dec 21 '17 at 21:46
  • My answer was not accepted and this question is 9 months old. Not to mention, *OP tagged jQuery in the question*. I appreciate your insight but if this answer isn't appropriate in your specific case, it doesn't mean the answer wasn't useful to the person who originally asked, or others who have come across it. Have a nice day. – Tyler Roper Dec 21 '17 at 21:53
0

Looks like the Page Visibility API paired with time absent calculations will do it. Documentation can be found here: https://developer.mozilla.org/en-US/docs/Web/API/Page_Visibility_API

The events get trigged when the window is visible / invisible, you don't have to click the page in order for it to detect. Exactly what I need.

IE 10+ mind. Although, not a problem for my app :p

Luka
  • 603
  • 6
  • 12