Countdown is stopping when user is out of current tab - javascript

I create a simple countdown with a "invert" progress bar - to control session in my website.
when time is over, page will be reload and without the session - blocked.
ISSUE:
The progress bar works fine - but IF the user change the window or the current tab - and "forgot" the page open - the countdown stops. I don't know why
THE CODE:
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(30, 30, $('#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>
JSFIDDLE: https://jsfiddle.net/2tonbd5k
Any idea to solve this?
I'm think I need to change the fixed "timeleft or timetotal" (+3Min) to a "real time" (user access the site at 21:57:00 then the "real time" to reload will be +3 minutes - 22:00:00 PM). If user go out, the animation will stop too - but when he returns the js will correct to the real time. I can update the "time" with ASP - but how I can do this?
** for test purposes timeleft in code is only 30s.

all you need is add this script
if ( document.hidden ) { return; }
the result is here
https://jsfiddle.net/mfkLea7w/

Related

How to add width to an element using jquery each function?

I want to build a loading bar effect using two seperate divs inside each other. I got it all positioned and all that but how can I make one of them increase its width from %1 to %100 with transition? I want it to be filled in 10 sec.
Thanks.
<div class="loading-container">
<div class="outside-loading"></div>
<div class="inside-loading"></div>
</div>
Fairly simple with jQuery animate() which you can customize for step or easing and also use callbacks for start or complete as needed
$('.outside-loading').animate({width: '100%'}, 3000);// using 3 sec for demo
.outside-loading {
background: blue;
width: 0;
height: .5em
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="loading-container">
<div class="outside-loading"></div>
<div class="inside-loading"></div>
</div>
Vanilla Javascript
Create a function and increase the width with your set interval function. Add a conditional that checks if the width is 100% and if it is, then clear the interval. I also moved the divs within each other and set the display of the inner span tag to inline-block...
You can also target the elements textContent and display the widths progress in percent as well...
var i = 0;
function move() {
if (i == 0) {
i = 1;
var elem = document.getElementsByClassName("inside-loading");
var width = 1;
var id = setInterval(frame, 100);
function frame() {
if (width >= 100) {
clearInterval(id);
i = 0;
} else {
width++;
elem[0].style.width = width + "%";
elem[0].textContent = width + "%";
}
}
}
}
move();
.outside-loading {
width: 100%;
height: 30px;
background-color: grey;
}
.inside-loading {
display: inline-block;
width: 1%;
height: 100%;
background-color: red;
text-align: right;
vertical-align: middle;
font-size: 30px;
font-weight: bold;
font-family: Arial, Helvetica, sans-serif;
}
<br><br><br>
<div class="loading-container">
<div class="outside-loading">
<span class="inside-loading">
</span>
</div>
</div>

Random name picker with bounce animation

I'm looking to create a random name picker with HTML, JS and CSS which has gone quite well as you can see here... http://clients.random.agency/namepicker/
However, the client has asked for it to have a similar animation to this with ...
https://www.dropbox.com/s/3likecb0ld30som/Jv0Gp4XkhQ.mp4?dl=0
I've search google but I can't seem to find any examples of what I'm looking for and would really appreciate if anyone could point me in the right direction.
This is a simple example, hope be helpful.
var names =['John', 'David', 'Joe', 'Sara'];
var nameCount= names.length;
var p = document.getElementById("container");
var randTimer = setInterval(function(){ p.innerHTML = names[Math.floor(Math.random() * nameCount)]; }, 200);
function stop(){
clearInterval(randTimer);
}
#container{
color: red;
font-size:2rem;
text-align:center;
cursor: pointer;
}
<p id="container" onClick="stop()"></p>
<p>click on random names to pick one!</P>
Here's a pretty similar example I was able to find. Using Javascript seems to be the most straightforward way to go about doing this. https://codepen.io/maerianne/pen/pRQbQr
var myScrollTop = function(elem, delay){
elem.animate({ scrollTop: 0 }, delay, function(){
myScrollBottom(elem, delay);
});
};
var myScrollBottom = function(elem, delay){
elem.animate({ scrollTop: elem.height() }, delay, function(){
myScrollTop(elem, delay);
});
};
var scrollUpDown = function(elem, delay) {
myScrollTop(elem, delay);
};
$(document).ready(function(){
scrollUpDown($(".scroll-up-down"), 5000);
});
As you can see, scrollUpDown()is the initial function which starts a loop switching between myScrollTop() and myScrollBottom(). You could pretty easily make the delay increase with each iteration to mimic the slowing down and eventual stop in the example animation you gave.
You could also refactor this to be a singular recursive function.
Best of luck!
It picks a random item from the array of labels. Then it goes into a loop, changing the label to the next item in the array until it gets to the chosen one, and using animation for the transitions
$('#search_btns button:nth-child(2)').hover(function() {
btnTimeID = setTimeout(function() {
// We are using the math object to randomly pick a number between 1 - 11, and then applying the formula (5n-3)5 to this number, which leaves us with a randomly selected number that is applied to the <ul> (i.e. -185) and corresponds to the position of a word (or <li> element, i.e. "I'm Feeling Curious").
var pos = -((Math.floor((Math.random() * 11) + 1)) * 5 - 3) * 5
if (pos === -135) {
console.log("position didn't change, let's force change")
pos = -35;
}
$('#search_btns button:nth-child(2) ul').animate({'bottom':pos + 'px'}, 300);
// Change the width of the button to fit the currently selected word.
if (pos === -35 || pos === -110 || pos === -185 || pos === -10 || pos === -60 || pos === -160) {
console.log(pos + ' = -35, -110, -185, -10, -60, -160');
$('#search_btns button:nth-child(2)').css('width', '149px');
} else if (pos === -85) {
console.log(pos + ' = -85');
$('#search_btns button:nth-child(2)').css('width', '160px');
} else if (pos === -210) {
console.log(pos + ' = -210');
$('#search_btns button:nth-child(2)').css('width', '165px');
} else {
console.log(pos + ' = -260, -235');
$('#search_btns button:nth-child(2)').css('width', '144px');
}
},200);
}, function() {
clearTimeout(btnTimeID);
setTimeout(function() {
console.log('setTimeout function');
$('#search_btns button:nth-child(2) ul').css('bottom', '-135px'); // this is the original position
$('#search_btns button:nth-child(2)').css('width', '144px'); // reset the original width of the button
},200);
});
body, html {
margin: 0;
box-sizing: border-box;
font-family: arial;
}
*, *:before, *:after {
box-sizing: inherit;
}
#search_btns {
width: 400px;
margin: 30px auto;
padding-left: 60px;
}
#search_btns button:nth-child(2) {
width: 144px;
}
#search_btns button:nth-child(1) {
bottom: 12px;
}
#search_btns button {
position: relative;
height: 34px;
margin: 3px;
font-weight: bold;
color: gray;
background: #f1f1f1;
border: 1px solid #f1f1f1;
border-radius: 2px;
padding: 0 15px;
overflow: hidden;
}
#search_btns button:hover {
color: black;
border: 1px solid #bdbdbd;
box-shadow: 0px 0.5px 0px 0px #d3d3d3;
}
#search_btns button:active {
border: 1px solid #7f7fff;
}
#search_btns button:focus {
outline: 0;
}
#search_btns button ul li {
list-style-type: none;
padding: 5px 0;
text-align: left;
}
#search_btns button ul {
padding-left: 0;
position: absolute;
bottom: -135px;
width: 144px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="search_btns">
<button>This might be the effect you looking for</button>
<button>
<ul>
<li>item0/li>
<li>item1</li>
<li>item2</li>
<li>item3</li>
<li>item4</li>
<li>item5</li>
<li>item6</li>
<li>item7</li>
<li>item8</li>
<li>item9</li>
</ul>
</button>
</div>
</body>
</html>

Create a Seekbar like vimeo video player (HTML5)

I tried to create a HTML5 video player from scratch. But I couldn't create a seekbar that slide nicely like vimeo(or youtube).
What I did is I added a extra div/span(that highlights the total viewed time) in the seekbar. Then I added mousedown & mousemove event.
When mousedown event get called I make a var(Boolean) true. While it is true and I change the width of the div/span according to the mousemove position.
It works, but It's unresponsive. I can't slide it seamlessly. So I wanted to know how can build a responsive seekbar like vimeo(youtube is same but youtube player has a dot like a range slider, but I don't want that). I prefer pure JavaScript without any frameware or API.
My Code:
HTML
<html>
<head>
<meta charset="utf-8" />
<title>Page Title</title>
</head>
<body>
<div class="container">
<video src="http://www.treatbd.com/Assets/vid.mp4" poster=""></video>
<div class="controls">
<!-- play/pause button -->
<div class="play"></div>
<!-- the seekbar -->
<div class="line">
<div class="elapsed"></div>
</div>
<div class="screen"></div>
</div>
</div>
</body>
</html>
CSS/SASS
html, body
margin: 0
padding: 0
background-color: #272b32
.container
height: 465px
width: 808px
margin: auto
margin-top: calc(50vh - 270px)
display: flex
flex-wrap: wrap
justify-content: center
position: relative
overflow: hidden
border-radius: 1px
video
background-color: aliceblue
object-position: center
width: 100%
height: 100%
display: block
object-fit: cover
.controls
background-color: transparent
width: 100%
height: 9%
position: absolute
left: 0
right: 0
bottom: 0
display: flex
transition: visibility 750ms
.controls *
box-sizing: border-box
border-left: 1px solid deepSkyblue
.play
display: inline-block
height: 100%
width: 7%
background: rgba(16,18,20, .4)
&:hover
background: rgba(16,18,20, .6)
.screen
display: inline-block
height: 100%
width: 7%
background: rgba(16,18,20, .4)
&:hover
background: rgba(16,18,20, .6)
.volume
display: none
.line
display: inline-block
height: 100%
width: 86%
background: rgba(0, 5, 7, 0.45)
position: relative
.elapsed
position: absolute
background: rgba(78, 144, 249, 0.4)
height: 100%
width: 0%
transition: width 200ms
JavaScript
var video = document.querySelector("video");
var playButton = document.querySelector(".play");
var elapsed = document.querySelector(".elapsed");
var line = document.querySelector(".line");
var duration = video.duration;
var playing = false;
var mouseDown = false;
// the play/pause button
playButton.addEventListener("click", function() {
if (playing) video.pause();
else video.play();
playing = !playing;
});
// click on the video to play/pause
video.addEventListener("click", function() {
if (playing) video.pause();
else video.play();
playing = !playing;
});
// seekbar
line.addEventListener("mousedown", function(e) {
// set current time according to mousedown position
video.currentTime = Number(
e.layerX / (line.clientWidth / 100) * (duration / 100)
).toFixed(1);
// change the width of elapsed bar.
elapsed.style.width = video.currentTime / (duration / 100) + "%";
mouseDown = true;
});
line.addEventListener("mousemove", function(e) {
if (mouseDown) {
video.currentTime = Number(
e.layerX / (line.clientWidth / 100) * (duration / 100)
).toFixed(1);
}
});
line.addEventListener("mouseup", () => (mouseDown = false));
// to let the metadata loaded
var dt = setInterval(function() {
if (video.readyState > 0) {
duration = Number(video.duration).toFixed(2);
clearTimeout(dt);
}
}, 50);
// highgligh the amount of played time. via a elapse bar
setInterval(function() {
elapsed.style.width = video.currentTime / (duration / 100) + "%";
}, 1000);
I was changing the currentTime according to mousemove.
line.addEventListener("mousemove", function(e) {
if (mouseDown) {
video.currentTime = Number(
e.layerX / (line.clientWidth / 100) * (duration / 100)
).toFixed(1);
}
});
and leaving the width of elapse bar to the currentTime. But I'm reading currentTime in every 1s.
setInterval(function() {
elapsed.style.width = video.currentTime / (duration / 100) + "%";
}, 1000);
That's why it's not responsive. Even if I slide quickly, the width of the elapse bar will only move after another second.
set the Interval to 10 (10 milliseconds)

progress bar countdown doesn't work

Hello i'm trying to put a progress bar countdown using the code bellow
function progress(timeleft, timetotal, $element) {
var progressBarWidth = timeleft * $element.width() / timetotal;
$element.find('div').animate({
width: progressBarWidth
}, 500).html(timeleft + " seconds to go");
if (timeleft > 0) {
setTimeout(function() {
progress(timeleft - 1, timetotal, $element);
}, 1000);
}
};
progress(20, 20, $('#progressBar'));
#progressBar {
width: 90%;
margin: 10px auto;
height: 22px;
background-color: #0A5F44;
}
#progressBar div {
height: 100%;
text-align: right;
padding: 0 10px;
line-height: 22px;
/* same as #progressBar height if we want text middle aligned */
width: 0;
background-color: #CBEA00;
box-sizing: border-box;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="progressBar">
<div></div>
</div>
but it doesn't work , when a refresh the page i see only "20 seconds to go" without the bar in background and i can't find out what's the problem
please can u tell me what are the possible causes of this problem ?
That can be, because Javascript is loaded completely new each time you refresh the page so will time left initiated to the same value.
You could use a cookie or phase the Value with i.e. PHP.
edit the javascript in this:
function progress(timeleft, timetotal, $element) {
var progressBarWidth = timeleft * $($element).width() / timetotal;
$($element).find('div').animate({
width: progressBarWidth
}, 500).html(timeleft + " seconds to go");
if (timeleft > 0) {
setTimeout(function() {
progress(timeleft - 1, timetotal, $element);
}, 1000);
}
};
heres the jsfiddle: https://jsfiddle.net/an1r77uo/

Countdown till the end of the year - JS

I'm working on a countdown in JS that going to count every second down to the end of 2016, at the end of 2016 I'll display a message to the user.
My issue is that I'm off by one hour from the actual time
I used this website(https://www.timeanddate.com/counters/newyear.html) to see if my countdown is displaying the correct time.
Here is my Code:
function updateTimer(deadline){
// going to give us the new date and time when this function was called which is every second.
// also getting back the date and time of the instance of updateTimer was called.
// time = deadline the point we're counting too - time of the function was called. (in milliseconds)
// the object is going to work out based on the time difference.
// Math Floor always round DOWN.
// time / 1000 = 1000 converted to seconds, 60 converted min,60 is hours, 24 is days
// time / 1000 = 1000 converted to seconds, 60 converted min,60 is hours % 24 == how many hours left in the particular day. 100 % 24 = 4 hours
var time = deadline - new Date();
return{
'days': Math.floor( time/(1000*60*60*24) ),
'hours': Math.floor( (time/(1000*60*60)) % 24),
'minutes': Math.floor( (time/1000/60) %60 ),
'seconds': Math.floor( (time/1000) %60 ),
'total': time
};
}
function animateClock(span){
span.className = "turn"; // giving a class turn into the injected span.
setTimeout(function(){
span.className = "";
},700);
}
// SetInterval going to be fired every second.
function startTimer(id,deadline){
var timerInterval = setInterval(function(){
var clock = document.getElementById(id); //getting the match id from the DOM.
var timer = updateTimer(deadline); // generating a function and injecting it a deadline.
// ref to the HTML with div clock - concat the series of spans
clock.innerHTML = '<span>' + timer.days + '</span>'
+'<span>' + timer.hours + '</span>'
+'<span>' + timer.minutes + '</span>'
+'<span>' + timer.seconds + '</span>';
// Animations
var spans = clock.getElementsByTagName("span"); // will get all the above spans that been injected to the clock div.
animateClock(spans[3]); // calling this function every second.
if(timer.seconds == 59) animateClock(spans[2]); // == 59 because we're going to be in a second 60 which is a minute.
if(timer.minutes == 59 && timer.seconds == 59) animateClock(spans[1]);
if(timer.hours == 23 && timer.minutes == 59 && timer.seconds == 59) animateClock(spans[0]); // when we getting to a new day.
// Check for the end of timer.
if(timer.total < 1){ //means the difference
clearInterval(timerInterval);
clock.innerHTML ='<span>0</span><span>0</span><span>0</span><span>0</span>';
}
},1000);
}
// when the window loads fire this function.
window.onload = function(){
var deadline = new Date("January 1, 2017 23:59:59"); // Declare a deadline.
startTimer("clock",deadline); // we're going to inject into the clock id of the html the deadline.
};
body{
background: #282e3a;
font-family: Tahoma;
}
h1{
color:#fff;
text-align: center;
font-size:74px;
letter-spacing: 10px;
}
#del-countdown{
width:850px;
margin: 15% auto;
}
#clock span{
float: left;
text-align: center;
font-size: 84px;
margin: 0 2.5%;
color:#fff;
padding: 20px;
width:20%;
border-radius: 20px;
box-sizing: border-box;
}
#clock span:nth-child(1){
background: #DA3B36;
}
#clock span:nth-child(2){
background: #2e6da4;
}
#clock span:nth-child(3){
background: #f6bc58;
}
#clock span:nth-child(4){
background: #5CB85C;
}
#clock:after{
content: "";
display: block;
clear: both;
}
#units span{
float: left;
width:25%;
text-align: center;
margin-top: 30px;
color:#ddd;
text-transform: uppercase;
font-size: 13px;
letter-spacing: 2px;
text-shadow: 1px 1px 1px 1px rgba(10,10,10,0.7);
}
span.turn{
animation: turn 0.5s ease forwards;
}
#keyframes turn{
0%{transform: rotatex(0deg)}
100%{transform: rotatex(360deg)}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Countdown</title>
<link href="style.css" rel="stylesheet" type="text/css">
</head>
<body>
<div id="del-countdown">
<h1>COUNTDOWN</h1>
<div id="clock"></div>
<div id="units">
<span>Days</span>
<span>Hours</span>
<span>Minutes</span>
<span>Seconds</span>
</div>
</div>
<script src="countdown.js"></script>
</body>
</html>
Your deadline should be:
var deadline = new Date("January 1, 2017 00:00:00")

Categories