Individually styling javascript output of a countdown timer - javascript

I'm trying to style the output of a javascript date counter. I need to be able to style the days, hours, minutes & seconds separately. I want to right align each in it's own div with it's own left and top absolute values. When I try to do that the timer does not replace the previous numbers, but adds to them, creating a big mess.
Here's the output code I am trying to style individually:
document.getElementById(id).innerHTML = days + 'days ';
document.getElementById(id).innerHTML += hours + 'hrs ';
document.getElementById(id).innerHTML += minutes + 'mins ';
document.getElementById(id).innerHTML += seconds + 'secs';
Here's a fiddle of it working fine but without separate styling
But, when I try to put them in separate divs crazy stuff happens, haha. The counter does not update, but just adds numbers instead.
Here's a fiddle of that
How do I do this?

When you are inserting the innerHTML values to the div, you can wrap the values inside a span with a class.
JSfiddle demo
document.getElementById(id).innerHTML = '<span class="days">' + days + 'days ';
document.getElementById(id).innerHTML += '<span class="hours">' + hours + 'hrs ';
document.getElementById(id).innerHTML += '<span class="minutes">' + minutes + 'mins ';
document.getElementById(id).innerHTML += '<span class="seconds">' + seconds + 'secs';
CountDownTimer('01/01/2016 10:01 AM', 'countdown');
function CountDownTimer(dt, id) {
var end = new Date(dt);
var _second = 1000;
var _minute = _second * 60;
var _hour = _minute * 60;
var _day = _hour * 24;
var timer;
function showRemaining() {
var now = new Date();
var distance = end - now;
if (distance < 0) {
clearInterval(timer);
document.getElementById(id).innerHTML = 'EXPIRED!';
return;
}
var days = Math.floor(distance / _day);
var hours = Math.floor((distance % _day) / _hour);
var minutes = Math.floor((distance % _hour) / _minute);
var seconds = Math.floor((distance % _minute) / _second);
document.getElementById(id).innerHTML = '<span class="days">' + days + 'days ';
document.getElementById(id).innerHTML += '<span class="hours">' + hours + 'hrs ';
document.getElementById(id).innerHTML += '<span class="minutes">' + minutes + 'mins ';
document.getElementById(id).innerHTML += '<span class="seconds">' + seconds + 'secs';
}
timer = setInterval(showRemaining, 1000);
}
#countdown {
position: absolute;
z-index: 5;
left: 20px;
top: 20px;
color: #ff0000;
font-family: Helvetica, Arial, sans-serif;
font-size: 32px;
display: inline;
}
.days {
color: lightblue;
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 1px 5px 0 rgba(0, 0, 0, 0.12);
padding: 10px;
}
.minutes {
color: tomato;
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 1px 5px 0 rgba(0, 0, 0, 0.12);
padding: 10px;
}
.seconds {
color: gray;
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 1px 5px 0 rgba(0, 0, 0, 0.12);
padding: 10px;
}
.hours {
color: tomato;
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 1px 5px 0 rgba(0, 0, 0, 0.12);
padding: 10px;
}
<div id="countdown">
</div>

If you will remove the line
document.getElementById(id).innerHTML = days + 'days ';
You will see "creating a big mess.". You must clear the div before put something to them.
document.getElementById(id).innerHTML = '';

Instead of adding all your time elements to a single I'd, create 4 separate divs inside the div you already have. Then use getElementById to put each time element inside it's own div.
That will allow you to use css to style each individually.

Related

Preventing CSS animation from restarting each time JS setInterval runs

I'm trying to add an intro animation to a timer using JS, but it seems to restart each time the function with a setinterval runs. The function updates the timer every second. This is my script:
function updateTimer(){
var target = Date.parse("9 January 2023, 00:00:00");
var today = new Date();
var diff = target - today;
var days = Math.floor(diff / (1000 * 60 * 60 * 24));
var hours = Math.floor(diff / (1000 * 60 * 60));
var mins = Math.floor(diff / (1000 * 60));
var secs = Math.floor(diff / 1000);
var days = days;
var hours = hours - days * 24;
var minutes = mins - hours * 60;
var seconds = secs - mins * 60;
document.getElementById("timer").innerHTML =
'<div>' + days + '<span> Days</span></div>' +
'<div>' + hours + '<span> Hours</span></div>' +
'<div>' + minutes + '<span> Minutes</span></div>' +
'<div>' + seconds + '<span> Seconds</span></div>';
}
setInterval('updateTimer()', 1000);
The script will show timer on the following HTML code:
<div id="timer">
<div><span>Days</span></div>
<div><span>Hours</span></div>
<div><span>Minutes</span></div>
<div><span>Seconds</span></div>
</div>
And the animation that im trying to apply has the following keyframes:
#keyframes timerSlideUp{
0%{
opacity: 0%; animation-delay: 5s;
}
100%{
opacity: 100%;
}
}
With the decorative CSS:
#timer{
color: white;
padding: 20px;
text-align: center;
}
#timer div{
display: inline-block;
min-width: 40px;
padding: 15px;
background: transparent;
border-radius: 3px;
border: 5px solid white;
margin-top: 30%;
margin-left: 5px;
margin-right: 5px;
text-align: center;
font-size: 2em;
font-weight: bold;
animation: timerSlideUp 5s forwards;
}
I haven't tried anything because I don't know at all how I could get around or fix this.
I'm trying to make the timer to fade in and stay in place (thus the "forwards" in the "animation" property). I'm planning to also add other animations in the future, so these restarts make it impossible.
Thanks in advance!
Move the animation up into the parent element and set animation-iteration-count to 1
I set a background: blue on the body as the white color didn't show anything when running the snippet
function updateTimer() {
var target = Date.parse("9 January 2023, 00:00:00");
var today = new Date();
var diff = target - today;
var days = Math.floor(diff / (1000 * 60 * 60 * 24));
var hours = Math.floor(diff / (1000 * 60 * 60));
var mins = Math.floor(diff / (1000 * 60));
var secs = Math.floor(diff / 1000);
var days = days;
var hours = hours - days * 24;
var minutes = mins - hours * 60;
var seconds = secs - mins * 60;
document.getElementById("timer").innerHTML =
'<div>' + days + '<span> Days</span></div>' +
'<div>' + hours + '<span> Hours</span></div>' +
'<div>' + minutes + '<span> Minutes</span></div>' +
'<div>' + seconds + '<span> Seconds</span></div>';
}
setInterval('updateTimer()', 1000);
body {
background: blue;
}
#keyframes timerSlideUp {
0% {
opacity: 0%;
animation-delay: 5s;
}
100% {
opacity: 100%;
}
}
#timer {
color: white;
padding: 20px;
text-align: center;
animation: timerSlideUp 5s forwards 1;
}
#timer div {
display: inline-block;
min-width: 40px;
padding: 15px;
background: transparent;
border-radius: 3px;
border: 5px solid white;
margin-top: 30%;
margin-left: 5px;
margin-right: 5px;
text-align: center;
font-size: 2em;
font-weight: bold;
}
<div id="timer">
<div><span>Days</span></div>
<div><span>Hours</span></div>
<div><span>Minutes</span></div>
<div><span>Seconds</span></div>
</div>

Implied eval. Consider passing a function instead of a string? [duplicate]

This question already has answers here:
How to eliminate error: "Implied eval is evil"
(5 answers)
How to change a settimeout into a function instead of a string
(2 answers)
Closed 10 months ago.
apologies for asking this when I've seen other threads where it was asked (similarly) but I"m not understanding the recommendations in previous posts. I'm very inexperienced with javascript and muddle through it here and there. Any help would be greatly appreciated.
I'm trying to create a countdown timer to a specific date. Locally the counter seems fine and it runs but upon going onto a dev environment is the an error:
"Implied eval. Consider passing a function instead of a string"
Here is the code I'm using:
function updateTimer() {
future = Date.parse("aug 24, 2022 01:30:00");
now = new Date();
diff = future - now;
days = Math.floor(diff / (1000 * 60 * 60 * 24));
hours = Math.floor(diff / (1000 * 60 * 60));
mins = Math.floor(diff / (1000 * 60));
secs = Math.floor(diff / 1000);
d = days;
h = hours - days * 24;
m = mins - hours * 60;
s = secs - mins * 60;
document.getElementById("timer")
.innerHTML =
'<div style="display:inline-block; min-width:90px; padding:15px; background:#000000; border-radius:10px; border:2px solid #0d0d0d; margin:6px;">' + d + '<span style="color: #58595B; display: block; margin-top: 6px; font-size: .35em; font-weight: 400;">DAYS</span></div>' +
'<div style="display:inline-block; min-width:90px; padding:15px; background:#000000; border-radius:10px; border:2px solid #0d0d0d; margin:6px;">' + h + '<span style="color: #58595B; display: block; margin-top: 6px; font-size: .35em; font-weight: 400;">HOURS</span></div>' +
'<div style="display:inline-block; min-width:90px; padding:15px; background:#000000; border-radius:10px; border:2px solid #0d0d0d; margin:6px;">' + m + '<span style="color: #58595B; display: block; margin-top: 6px; font-size: .35em; font-weight: 400;">MINUTES</span></div>' +
'<div style="display:inline-block; min-width:90px; padding:15px; background:#000000; border-radius:10px; border:2px solid #0d0d0d; margin:6px;">' + s + '<span style="color: #58595B; display: block; margin-top: 6px; font-size: .35em; font-weight: 400;">SECONDS</span></div>';
}
setInterval('updateTimer()', 1000);
The error is on the last line.
Thank you in advance

Clock hand rotation reverting back to original position at 360deg

I was following this challenge which ended with fixing this clocks hands.
Whenever the second's hand reaches the 12 o'clock position, the entire animation restarts but pulls the hand backwards so the next tick at 1-second isnt seamless, and it looks ugly.
how can I achieve this?
const secondHand = document.querySelector('.second-hand');
function setDate(){
const now = new Date();
const seconds = now.getSeconds();
const secondsDegrees = ((seconds / 60) * 360) + 90;
secondHand.style.transform = `rotate(${secondsDegrees}deg)`;
}
setInterval(setDate, 1000);
setDate();
.clock {
width: 30rem;
height: 30rem;
border: 20px solid white;
border-radius: 50%;
margin: 50px auto;
position: relative;
padding: 2rem;
box-shadow:
0 0 0 4px rgba(0,0,0,0.1),
inset 0 0 0 3px #EFEFEF,
inset 0 0 10px black,
0 0 10px rgba(0,0,0,0.2);
}
.clock-face {
position: relative;
width: 100%;
height: 100%;
transform: translateY(-3px); /* account for the height of the clock hands */
}
.hand {
width: 50%;
height: 6px;
background: black;
position: absolute;
top: 50%;
transform-origin: 100%;
transform: rotate(90deg);
transition: all 0.05s;
transition-timing-function: cubic-bezier(0.38, 2.9, 0.58, 1);
}
<div class="clock">
<div class="clock-face">
<div class="hand hour-hand"></div>
<div class="hand min-hand"></div>
<div class="hand second-hand"></div>
</div>
</div>
<br>
You need to set your seconds hand to 360 degrees, disable its transition, set it to 0 degrees, then enable its transition. Note that you should only disable the transition after the previous transition is over:
function setDate() {
const now = new Date();
const seconds = now.getSeconds();
const secondsDegrees = ((seconds / 60) * 360) + 90;
if(secondsDegrees == 0) {
secondHand.style.transform = "rotate(360deg)";
setTimeout(function() {
secondHand.style.transition = "0s";
secondHand.style.transform = "rotate(0deg)";
secondHand.style.transition = "";
},50);
} else {
secondHand.style.transform = `rotate(${secondsDegrees}deg)`;
}
}
You will probably need to do this for the minutes and hours hands too.

Change HTML Button style when click not working in Javascript

I want to change a button color when click the button. This is the code that I used.
function abc() {
var color = document.getElementById("btn").style.background - color;
if (background - color === "#c1580b")
document.getElementById("btn").style.cssText = "box-shadow: 0px 0px 0px 3px #173B0B; background-color: #173B0B; color:#459c5c";
else
document.getElementById("btn").style.cssText = "box-shadow: 0px 0px 0px 3px #c1580b; background-color: #c1580b; color:#ffb734";
}
.btn {
background: #c1580b;
color: #ffb734;
width: 80px;
height: 80px;
line-height: 70px;
display: block;
border-radius: 50%;
text-align: center;
text-decoration: none;
border: 2px solid #000;
box-shadow: 0px 0px 0px 3px #c1580b;
font-size: medium;
}
<button id="btn" class="btn" onclick="abc()">Pause</button>
But this is not working.
I did not quite understand that part of the background - color, but to check the background in hex, you have to go from hex to rgb.
Can see here more examples of how to pass hex to rgb - https://stackoverflow.com/a/4090628/8098173
Here's an example of what you want.
function abc() {
var bt = document.getElementById('btn');
var style = bt.currentStyle || window.getComputedStyle(bt);
var bcolor = rgb2hex(style.backgroundColor);
if (bcolor === '#c1580b') {
bt.style.cssText = "box-shadow: 0px 0px 0px 3px #173B0B; background-color: #173B0B; color:#459c5c";
} else {
bt.style.cssText = "box-shadow: 0px 0px 0px 3px #c1580b; background-color: #c1580b; color:#ffb734";
}
}
// pass rbg to hex
function rgb2hex(rgb) {
if ( rgb.search("rgb") == -1 ) {
return rgb;
} else {
rgb = rgb.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*(\d+))?\)$/);
function hex(x) {
return ("0" + parseInt(x).toString(16)).slice(-2);
}
return "#" + hex(rgb[1]) + hex(rgb[2]) + hex(rgb[3]);
}
}
.btn {
background: #c1580b;
color: #ffb734;
width: 80px;
height: 80px;
line-height: 70px;
display: block;
border-radius: 50%;
text-align: center;
text-decoration: none;
border: 2px solid #000;
box-shadow: 0px 0px 0px 3px #c1580b;
font-size: medium;
}
<button id="btn" class="btn" onclick="abc()">Pause</button>
Here you have a working code.
I would suggest you to avoid the inline onclick="abc()" and opt in favor of a fully-separated code using EventListener (that's good for maintainability).
With Window.getComputedStyle() you get the background color in RGBA; you can then convert it to the HEX code with a simple function that you can find everywhere on the Web, here I used one of them. So, the right way to get the background color is window.getComputedStyle(btn, null)["backgroundColor"] while, if you would like to set it, the correct form would be document.getElementById("btn").style.backgroundColor = "#0000".
/**
* The code inside the function is run only when the DOM is ready.
* This is the only jQuery function used, all the rest is in vanillaJS.
*/
$(document).ready(function() {
/**
* rgb2hex
* Convert RGB to HEX.
* Source: https://jsfiddle.net/Mottie/xcqpF/1/light/
*
* #param {string} rgb
*/
var rgb2hex = function(rgb){
rgb = rgb.match(/^rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?/i);
return (rgb && rgb.length === 4) ? "#" +
("0" + parseInt(rgb[1],10).toString(16)).slice(-2) +
("0" + parseInt(rgb[2],10).toString(16)).slice(-2) +
("0" + parseInt(rgb[3],10).toString(16)).slice(-2) : '';
}
/**
* EventListener of btn click event
*/
document.getElementById("btn")
.addEventListener('click', function() {
// Save the btn into a var so you can use it later
var btn = document.getElementById("btn");
// Notice: getComputedStyle() to get the element background color
var color = window.getComputedStyle(btn, null)["backgroundColor"];
// Transform RGBa to HEX
var hex = rgb2hex(color);
// IF-ELSE with ternary operators
(hex === "#c1580b")
? btn.style.cssText = "box-shadow: 0px 0px 0px 3px #173B0B; background-color: #173B0B; color:#459c5c"
: btn.style.cssText = "box-shadow: 0px 0px 0px 3px #c1580b; background-color: #c1580b; color:#ffb734";
});
});
.btn {
background: #c1580b;
color: #ffb734;
width: 80px;
height: 80px;
line-height: 70px;
display: block;
border-radius: 50%;
text-align: center;
text-decoration: none;
border: 2px solid #000;
box-shadow: 0px 0px 0px 3px #c1580b;
font-size: medium;
cursor: pointer;
}
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
</head>
<body>
<button id="btn" class="btn">Pause</button>
</body>
</html>
if always you use this color in HEX format (#c1580b), So:
function abc() {
var elm = document.getElementById( 'btn' );
var color = window.getComputedStyle( elm ).backgroundColor;
if ( color === 'rgb(193, 88, 11)' )
elm.style.cssText = 'box-shadow: 0 0 0 3px #173B0B; background-color: #173B0B; color: #459c5c'
else
elm.style.cssText = 'box-shadow: 0 0 0 3px #c1580b; background-color: #c1580b; color: #ffb734'
}
Your code contains some logical error. The if condition has no sense : background - color means «substract the value of color to the value of background (which seems to be undefined).
To get the background color of the button, you need the following
background = document.getElementById("btn").style.backgroundColor;
if (background === "#c1580b")

How do i use the code that read the text file that was working with the code that scroll the text in the red box?

I want tht in the end it will read from the text file each time two lines display them and scroll them up in the Red box Latest News.
This is what i tried to do:
<script type='text/javascript' src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<script type='text/javascript' src="http://vaakash.github.io/jquery/easy-ticker.js"></script>
<style>
.demof{
border: 1px solid #ccc;
margin: 25px 0;
}
.demof ul{
padding: 0;
list-style: none;
}
.demof li{
padding: 20px;
border-bottom: 1px dashed #ccc;
}
.demof li.odd{
background: #fafafa;
}
.demof li:after {
content: '';
display: block;
clear: both;
}
.demof img{
float: left;
width: 100px;
margin: 5px 15px 0 0;
}
.demof a{
font-family: Arial, sans-serif;
font-size: 20px;
font-weight: bold;
color: #06f;
}
.demof p {
margin: 15px 0 0;
font-size: 14px;
}
.demo3 {
font-family: Arial, sans-serif;
border: 1px solid #C20;
margin: 50px 0;
font-style: italic;
position: relative;
padding: 0 0 0 110px;
box-shadow: 0 2px 5px -3px #000;
border-radius: 3px;
}
.demo3:before {
content: "Latest News";
display: inline-block;
font-style: normal;
background: #C20;
padding: 10px;
color: #FFF;
font-weight: bold;
position: absolute;
top: 0;
left: 0;
}
.demo3:after {
content: '';
display: block;
top: 0;
left: 80px;
background: linear-gradient(#FFF, rgba(255, 255, 255, 0));
height: 20px;
}
.demo3 ul li {
list-style: none;
padding: 10px 0;
}
</style>
<script>
var count = 300;
var counter = setInterval(timer, 1000); //1000 will run it every 1 second
function timer() {
count = count - 1;
if (count == -1) {
clearInterval(counter);
return;
}
var seconds = count % 60;
var minutes = Math.floor(count / 60);
var hours = Math.floor(minutes / 60);
minutes %= 60;
hours %= 60;
document.getElementById("timer").innerHTML = hours + " Hours " + minutes + " Minutes and " + seconds + " Seconds left untill the next news update."; // watch for spelling
}
function news(){
$('body').find('.newsticker').remove();//It will clear old data if its present
var file = "http://newsxpressmedia.com/files/theme/test.txt";
$.get(file, function (txt) {
//var lines = txt.responseText.split("\n");
var lines = txt.split("\n");
$ul = $('<ul class="demo3" />');
for (var i = 0, len = lines.length; i < len; i++) {
//save(lines[i]); // not sure what this does
$ul.append('<li>' + lines[i] + '</li>'); //here
}
//$ul.appendTo('body').newsTicker({
$ul.appendTo('div.wcustomhtml').newsTicker({
row_height: 48,
max_rows: 2,
speed: 6000,
direction: 'up',
duration: 1000,
autostart: 1,
pauseOnHover: 1
});
});
}
$(function() {
news();
setInterval(function(){
news();
},30000) // it will call every 1 min you can change it
});
</script>
<br><br><span id="timer"></span><br><br>
The result is that i see all the text from the text file in the red box Latest News and it dosent scroll up.
Not what i wanted at all.
You can see the result here on my site:
My Site
What i changed was only in one line :
$ul = $('<ul class="demo3" />');
Instead demo3 there was newsticker
You have the name of the plugin wrong - it is easyTicker, not newsTicker
change
$ul.appendTo('div.wcustomhtml').newsTicker({
to
$ul.appendTo('div.wcustomhtml').easyTicker({
and see if that works

Categories

Resources