I use a code for a countdown, which works but I don't like how it displays (in red)
As you can see, it displays on 8 lines, I would like one
By so I understand with the code, it is because of this section:
Plus que <strong><font color="#ff0000">
<div id="clockdiv">
<span class="days"></span><div class="smalltext">jours</div>
<span class="hours"></span><div class="smalltext">hrs</div>
<span class="minutes"></span><div class="smalltext">mins</div>
<span class="seconds"></span><div class="smalltext">secs</div>
</font></strong> pour profiter de la promotion !
</div>
But "div" and "span" should not force the text to the next line, unlike a "br"
Any idea of the issue?
Your help would be greatly appreciated, thanks :)
If needed, this is the entire code of the countdown
<li class="limite">
Plus que <strong><font color="#ff0000">
<div id="clockdiv">
<span class="days"></span><div class="smalltext">jours</div>
<span class="hours"></span><div class="smalltext">hrs</div>
<span class="minutes"></span><div class="smalltext">mins</div>
<span class="seconds"></span><div class="smalltext">secs</div>
</font></strong> pour profiter de la promotion !
</div>
<script type="text/javascript">
function getTimeRemaining(endtime) {
var t = Date.parse(endtime) - Date.parse(new Date());
var seconds = Math.floor((t / 1000) % 60);
var minutes = Math.floor((t / 1000 / 60) % 60);
var hours = Math.floor((t / (1000 * 60 * 60)) % 24);
var days = Math.floor(t / (1000 * 60 * 60 * 24));
return {
'total': t, 'days': days, 'hours': hours, 'minutes': minutes, 'seconds': seconds
};
}
function initializeClock(id, endtime) {
var clock = document.getElementById(id);
var daysSpan = clock.querySelector('.days');
var hoursSpan = clock.querySelector('.hours');
var minutesSpan = clock.querySelector('.minutes');
var secondsSpan = clock.querySelector('.seconds');
function updateClock() {
var t = getTimeRemaining(endtime);
daysSpan.innerHTML = ('0' + t.days).slice(-2);
hoursSpan.innerHTML = ('0' + t.hours).slice(-2);
minutesSpan.innerHTML = ('0' + t.minutes).slice(-2);
secondsSpan.innerHTML = ('0' + t.seconds).slice(-2);
if (t.total <= 0) {
clearInterval(timeinterval);
}
}
updateClock();
var timeinterval = setInterval(updateClock, 1000);
}
var timeInDays = 12;
var timeInMinutes = 4;
var timeInSeconds = 26;
var currentTime = Date.parse(new Date());
if(document.cookie && document.cookie.match('myClock')){
var deadline = document.cookie.match(/(^|;)myClock=([^;]+)/)[2];
}
else{
var deadline = new Date(currentTime + timeInDays*60*60*1000 + timeInMinutes*60*1000 + timeInSeconds*1000);
document.cookie = 'myClock=' + deadline + '; path=/; domain=. https://www.tresor-ethnique.com/';
initializeClock('clockdiv', deadline);
}
</script>
</li>
A <div> element is a "block-level" element, meaning it always renders on its own line.
A <span> element is an "inline" element, meaning that it flows "inline" with the other content.
To get what you want, you have two options:
Change <div class="smalltext">...</div> to <span
class="smalltext">...</span>
In your CSS smalltext class, add: display:inline;
A div is a block-level element. You could do two things.
1. Make the div an inline element.
div {
display: inline;
}
2. Make the whole one div.
Plus que <strong><font color="#ff0000">
<div id="clockdiv">
<div class="smalltext">
<span class="days"></span>jours
<span class="hours"></span>hrs
<span class="minutes"></span>mins
<span class="seconds"></span>secs
</div>
</font></strong> pour profiter de la promotion !
</div>
div is a block element, so it will indeed force a new line.
Add some CSS:
div {
display: inline;
}
Make your div float:left
.left{
float: left;
padding: 5px;
}
<li class="limite">
Plus que <strong><font color="#ff0000">
<div id="clockdiv">
<span class="days"></span><div class="smalltext left">jours</div>
<span class="hours"></span><div class="smalltext left">hrs</div>
<span class="minutes"></span><div class="smalltext left">mins</div>
<span class="seconds"></span><div class="smalltext left">secs</div>
Just don't use divs if you have only flow content.
By default, div is "display: block", which produces the line break. You could prevent line breaks by replacing div's by span's (which has "display: inline" by default).
Another option is change display property for div's you don't want line breaks, example:
<style type="text/css">
.no-ln-bk
{
display: inline
}
</style>
<div class="smalltext no-ln-bk">my text 1</div>
<div class="smalltext no-ln-bk">my text 2</div>
Related
I am beginner in HTML and I am trying to put a timer in my HTML university project daily word game that shows time left until the next day and word. I found a W3Schools tutorial for a timer but it does not work for me because it is until constant date.
My code looks like this:
<!DOCTYPE html>
<html>
<head>
<link rel="icon" href="images/tabIcon.ico">
<title>Daily WordGame</title>
<style>
h1 {
font-family: Tahoma, sans-serif;
text-align: center;
}
p {
font-size: large;
text-align: center;
}
</style>
</head>
<body>
<h1>Welcome to your daily source of educational fun</h1>
<hr>
<p style="font-size: large;">Everyday you have a chance of guessing a different word.
</p>
Go to about
<p>this is a second text</p>
<ul>
<li>Boats</li>
<li>Cars</li>
<ul>
<li>Buggati</li>
<table>
<tr>
<td>Price</td>
<td>Top speed</td>
<td>0-100</td>
<td>Horse Power</td>
</tr>
<tr>
<td>3.300.000$</td>
<td>420km/h</td>
<td>2.2s</td>
<td>1480</td>
</tr>
</table>
<img src="images/car.jpg" style="width: 500px;height:300px;">
</ul>
<li>Trucks</li>
</ul>
</body>
<html>
Add a span or any text element with an id of timer
<span id="timer">Time until next word: </span>
And add JavaScript code to get the countdown
<script>
var now = new Date();
// If you want another time, set it here with javascrip Date API
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date
var tomorrow = new Date().setDate(now.getDate() + 1);
var timer = document.getElementById("timer");
// Update the count down every 1 second
setInterval(() => {
// Fill in with the time until tomorrow
var time = new Date(tomorrow - now);
var hours = time.getHours();
var minutes = time.getMinutes();
var seconds = time.getSeconds();
// Format the time to add a leading 0 if less than 10
function fillZero(n) {
if (n < 10) {
return "0" + n;
} else return n.toString();
}
timer.innerText = "Time until next word: " + "0d " + fillZero(hours) + "h " + fillZero(minutes) + "m " + fillZero(seconds) + "s";
}, 1000);
</script>
So the modified code with your HTML is
<!DOCTYPE html>
<html>
<head>
<link rel="icon" href="images/tabIcon.ico">
<title>Daily WordGame</title>
<style>
h1 {
font-family: Tahoma, sans-serif;
text-align: center;
}
p {
font-size: large;
text-align: center;
}
</style>
</head>
<body>
<h1>Welcome to your daily source of educational fun</h1>
<hr>
<p style="font-size: large;">Everyday you have a chance of guessing a different word.
</p>
Go to about
<p>this is a second text</p>
<span id="timer">Time until next word: </span>
<ul>
<li>Boats</li>
<li>Cars</li>
<ul>
<li>Buggati</li>
<table>
<tr>
<td>Price</td>
<td>Top speed</td>
<td>0-100</td>
<td>Horse Power</td>
</tr>
<tr>
<td>3.300.000$</td>
<td>420km/h</td>
<td>2.2s</td>
<td>1480</td>
</tr>
</table>
<img src="images/car.jpg" style="width: 500px;height:300px;">
</ul>
<li>Trucks</li>
</ul>
<script>
var now = new Date();
// If you want another time, set it here with javascrip Date API
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date
var tomorrow = new Date().setDate(now.getDate() + 1);
var timer = document.getElementById("timer");
// Update the count down every 1 second
setInterval(() => {
// Fill in with the time until tomorrow
var time = new Date(tomorrow - now);
var hours = time.getHours();
var minutes = time.getMinutes();
var seconds = time.getSeconds();
// Format the time to add a leading 0 if less than 10
function fillZero(n) {
if (n < 10) {
return "0" + n;
} else return n.toString();
}
timer.innerText = "Time until next word: " + "0d " + fillZero(hours) + "h " + fillZero(minutes) + "m " + fillZero(seconds) + "s";
}, 1000);
</script>
</body>
<html>
The Problem: the first time my code runs perfectly fine, and when I reset it through reset button, it reset all the output in Document, but problem comes here when I run the code again by clicking on "CLICK ME" button it wont run and shows the error(Cannot read property 'appendChild' of null ageCalculator.) ["ageCalculator is Function Name"]
CODE: Please Refer the code below..>>>
Screenshot of error:
function ageCalculator(){
let birthyear = prompt('what is your birth year ?');
/*................FOR AGE IN YEAR.......................*/
let ageInyear = (2020-birthyear); //formula to calculate age by years.
let ageh5 = document.createElement('p');
let yearAnswer = document.createTextNode('You are ' + ageInyear + ' years old.');
ageh5.setAttribute('id','ageyear');
ageh5.appendChild(yearAnswer);
document.getElementById('ageinyears').appendChild(ageh5);
//console.log('year success');//display in console
/*................FOR AGE IN MONTH.......................*/
let ageMonth =(ageInyear * 12);
let agemon = document.createElement('p');
let monthAnswer = document.createTextNode('You are ' + ageMonth + ' old');
agemon.setAttribute('id','ageinMonth');
agemon.appendChild(monthAnswer);
document.getElementById('ageInMonth').appendChild(agemon);
//console.log('month success');
/*................FOR AGE IN DAYS.......................*/
let ageInDays = (2020-birthyear)*365; //formula for calculating age in days.
let agep = document.createElement('p'); //creating p or (h3,h4,h5) tag through js
let daysAnswer = document.createTextNode('You are '+ ageInDays + ' days.') //message that will be displayed on output.
agep.setAttribute('id', 'ageinDays'); // creating id to h4and giving id name ageInDays.
agep.appendChild(daysAnswer); //h5 child (sentence) display.
document.getElementById('ageInDays').appendChild(agep); //targeting id from HTML doc and adding h4 attribute to it (which is created in JS).
//console.log('day success '); //display in console.
/*................FOR AGE IN HOURS.......................*/
let agehours = (ageInyear * 12 * 30 * 24); //formula to calculate age in hours
let agehr = document.createElement('p');
let hrAnswer = document.createTextNode('You are ' + agehours + ' hours old');
agehr.setAttribute('id','ageinhr');
agehr.appendChild(hrAnswer);
document.getElementById('ageinhours').appendChild(agehr);
//console.log('hour success');//display in console
/*................FOR AGE IN MINUTES.......................*/
let ageminute = (ageInyear * 12 * 30 * 24 * 60);
let agemin = document.createElement('p');
let minAnswer = document.createTextNode('You are ' + ageminute + ' minute old');
agemin.setAttribute('id','minuteage');
agemin.appendChild(minAnswer);
document.getElementById('ageinminutes').appendChild(agemin);
//console.log('minute success');
/*................FOR AGE IN SECONDS.......................*/
let agesec = (ageInyear * 12 * 30 * 24 * 60 * 60);
let ageinsec = document.createElement('p');
let secAnswer = document.createTextNode('You are ' + agesec + ' seconds old');
ageinsec.setAttribute('id','secINage');
ageinsec.appendChild(secAnswer);
document.getElementById('ageinsecounds').appendChild(ageinsec);
//console.log('second success');
}
function reset(){
document.getElementById('ageinyears').remove();
document.getElementById('ageInDays').remove();
document.getElementById('ageInMonth').remove();
document.getElementById('ageinhours').remove();
document.getElementById('ageinminutes').remove();
document.getElementById('ageinsecounds').remove();
console.log('reset success');
}
*{
margin: 0;
padding: 0;
}
.flex-container{
display: flex;
border: 1px solid black;
padding: 15px;
flex-wrap: wrap;
justify-content: space-around;
flex-direction: row;
}
.flex-container-result div{
margin-top: 2px;
border: 1px solid red;
display: flex;
padding: 10px;
justify-content: center;
}
.flex-container-result label{
font-size: 18px;
font-weight: bold;
text-transform: capitalize;
display: flex;
flex-direction: column;
}
<body>
<div class="container">
<h2>Age Calclator.</h2>
<div class="flex-container">
<div>
<button type="button" class="btn btn-primary mr-5" onclick="ageCalculator()"><b>click me</b></button>
</div>
<div>
<button type="button" class="btn btn-danger mr-4" onclick="reset()"><b>Reset</b></button>
</div>
</div>
<div class="flex-container-result">
<div id="ageinyears">
<label>age in years :  </label>
</div>
<div id="ageInDays">
<label>age in days :  </label>
</div>
<div id="ageInMonth">
<label>age in month :  </label>
</div>
<div id="ageinhours">
<label>age in hours :  </label>
</div>
<div id="ageinminutes">
<label>age in minutes :  </label>
</div>
<div id="ageinsecounds">
<label>age in secounds :  </label>
</div>
</div>
</div>
<script src="proj1.js"></script>
</body>
The problem is all here.
function reset(){
document.getElementById('ageinyears').remove();
document.getElementById('ageInDays').remove();
document.getElementById('ageInMonth').remove();
document.getElementById('ageinhours').remove();
document.getElementById('ageinminutes').remove();
document.getElementById('ageinsecounds').remove();
console.log('reset success');
}
Change to
function reset(){
document.getElementById('ageyear').remove();
document.getElementById('ageinDays').remove();
document.getElementById('ageinMonth').remove();
document.getElementById('ageinhr').remove();
document.getElementById('minuteage').remove();
document.getElementById('secINage').remove();
console.log('reset success');
}
Let me explain
Initially each parent (div[id="ageinyears"], div[id="ageInDays"], div[id="ageInMonth"], div[id="ageinhours"], div[id="ageinminutes"], div[id="ageinminutes"], div[id="ageinsecounds"]) have only 1 child = Lable
when the user clicks on the button click me, you have logic to give birth to another child for each parent; New childs = (p[id="ageyear"], p[id="ageinDays"], p[id="ageinMonth"], p[id="ageinhr"], p[id="minuteage"], p[id="secINage"])
The problem is... When the user clicks on the button reset using remove() method, you are commanding to kill few parents + few newborn babies instead of ONLY the newborn babies of the parents.. and all the newborn babies are required for your logic ID.appendChild() + Bonus:... This unethical Error/killing is happening just because of the wrong Ids.
Additional Help
You should handle the Reset button properly; I mean something like...
Initial state of Reset: disabled
<button type="button" id="reset" class="btn btn-danger mr-4" onclick="reset()" disabled><b>Reset</b></button>
Enable it after a successful age calculation
document.getElementById("reset").disabled = false;
Disable it again after the reset
document.getElementById("reset").disabled = true;
<!DOCTYPE html>
<meta name="robots" content="noindex">
<html>
<head>
<style>
*{
margin: 0;
padding: 0;
}
.flex-container{
display: flex;
border: 1px solid black;
padding: 15px;
flex-wrap: wrap;
justify-content: space-around;
flex-direction: row;
}
.flex-container-result div{
margin-top: 2px;
border: 1px solid red;
display: flex;
padding: 10px;
justify-content: center;
}
.flex-container-result label{
font-size: 18px;
font-weight: bold;
text-transform: capitalize;
display: flex;
flex-direction: column;
}
</style>
</head>
<body>
<body>
<div class="container">
<h2>Age Calclator.</h2>
<div class="flex-container">
<div>
<button type="button" class="btn btn-primary mr-5" onclick="ageCalculator()"><b>click me</b></button>
</div>
<div>
<button type="button" id="reset" class="btn btn-danger mr-4" onclick="reset()" disabled><b>Reset</b></button>
</div>
</div>
<div class="flex-container-result">
<div id="ageinyears">
<label>age in years :  </label>
</div>
<div id="ageInDays">
<label>age in days :  </label>
</div>
<div id="ageInMonth">
<label>age in month :  </label>
</div>
<div id="ageinhours">
<label>age in hours :  </label>
</div>
<div id="ageinminutes">
<label>age in minutes :  </label>
</div>
<div id="ageinsecounds">
<label>age in secounds :  </label>
</div>
</div>
</div>
<script src="proj1.js"></script>
</body>
<script id="jsbin-javascript">
function ageCalculator(){
let birthyear = prompt('what is your birth year ?');
/*................FOR AGE IN YEAR.......................*/
let ageInyear = (2020-birthyear); //formula to calculate age by years.
let ageh5 = document.createElement('p');
let yearAnswer = document.createTextNode('You are ' + ageInyear + ' years old.');
ageh5.setAttribute('id','ageyear');
ageh5.appendChild(yearAnswer);
document.getElementById('ageinyears').appendChild(ageh5);
//console.log('year success');//display in console
/*................FOR AGE IN MONTH.......................*/
let ageMonth =(ageInyear * 12);
let agemon = document.createElement('p');
let monthAnswer = document.createTextNode('You are ' + ageMonth + ' old');
agemon.setAttribute('id','ageinMonth');
agemon.appendChild(monthAnswer);
document.getElementById('ageInMonth').appendChild(agemon);
//console.log('month success');
/*................FOR AGE IN DAYS.......................*/
let ageInDays = (2020-birthyear)*365; //formula for calculating age in days.
let agep = document.createElement('p'); //creating p or (h3,h4,h5) tag through js
let daysAnswer = document.createTextNode('You are '+ ageInDays + ' days.') //message that will be displayed on output.
agep.setAttribute('id', 'ageinDays'); // creating id to h4and giving id name ageInDays.
agep.appendChild(daysAnswer); //h5 child (sentence) display.
document.getElementById('ageInDays').appendChild(agep); //targeting id from HTML doc and adding h4 attribute to it (which is created in JS).
//console.log('day success '); //display in console.
/*................FOR AGE IN HOURS.......................*/
let agehours = (ageInyear * 12 * 30 * 24); //formula to calculate age in hours
let agehr = document.createElement('p');
let hrAnswer = document.createTextNode('You are ' + agehours + ' hours old');
agehr.setAttribute('id','ageinhr');
agehr.appendChild(hrAnswer);
document.getElementById('ageinhours').appendChild(agehr);
//console.log('hour success');//display in console
/*................FOR AGE IN MINUTES.......................*/
let ageminute = (ageInyear * 12 * 30 * 24 * 60);
let agemin = document.createElement('p');
let minAnswer = document.createTextNode('You are ' + ageminute + ' minute old');
agemin.setAttribute('id','minuteage');
agemin.appendChild(minAnswer);
document.getElementById('ageinminutes').appendChild(agemin);
//console.log('minute success');
/*................FOR AGE IN SECONDS.......................*/
let agesec = (ageInyear * 12 * 30 * 24 * 60 * 60);
let ageinsec = document.createElement('p');
let secAnswer = document.createTextNode('You are ' + agesec + ' seconds old');
ageinsec.setAttribute('id','secINage');
ageinsec.appendChild(secAnswer);
document.getElementById('ageinsecounds').appendChild(ageinsec);
document.getElementById("reset").disabled = false;
//console.log('second success');
}
function reset(){
document.getElementById('ageyear').remove();
document.getElementById('ageinDays').remove();
document.getElementById('ageinMonth').remove();
document.getElementById('ageinhr').remove();
document.getElementById('minuteage').remove();
document.getElementById('secINage').remove();
console.log('reset success');
document.getElementById("reset").disabled = true;
}
</script>
</body>
</html>
Note: Yes, this will solve your problem but, seriously this is not the proper way of handling things in real-time but Squint is better than blindness right... so as of now you can use this piece, but, I suggest you to focus more on things by analysing real-time scenarios and code issues :)
Here is your code.
When you resest it you removed html element from document. And second time when you want to calculate and write result to element there is no that element. And it gives you error. You need just clear it.
just replace
document.getElementById('ageinyears').remove();
to
document.getElementById('ageinyears').innerHTML = "your initial html code"
function ageCalculator(){
let birthyear = prompt('what is your birth year ?');
/*................FOR AGE IN YEAR.......................*/
let ageInyear = (2020-birthyear); //formula to calculate age by years.
let ageh5 = document.createElement('p');
let yearAnswer = document.createTextNode('You are ' + ageInyear + ' years old.');
ageh5.setAttribute('id','ageyear');
ageh5.appendChild(yearAnswer);
document.getElementById('ageinyears').appendChild(ageh5);
//console.log('year success');//display in console
/*................FOR AGE IN MONTH.......................*/
let ageMonth =(ageInyear * 12);
let agemon = document.createElement('p');
let monthAnswer = document.createTextNode('You are ' + ageMonth + ' old');
agemon.setAttribute('id','ageinMonth');
agemon.appendChild(monthAnswer);
document.getElementById('ageInMonth').appendChild(agemon);
//console.log('month success');
/*................FOR AGE IN DAYS.......................*/
let ageInDays = (2020-birthyear)*365; //formula for calculating age in days.
let agep = document.createElement('p'); //creating p or (h3,h4,h5) tag through js
let daysAnswer = document.createTextNode('You are '+ ageInDays + ' days.') //message that will be displayed on output.
agep.setAttribute('id', 'ageinDays'); // creating id to h4and giving id name ageInDays.
agep.appendChild(daysAnswer); //h5 child (sentence) display.
document.getElementById('ageInDays').appendChild(agep); //targeting id from HTML doc and adding h4 attribute to it (which is created in JS).
//console.log('day success '); //display in console.
/*................FOR AGE IN HOURS.......................*/
let agehours = (ageInyear * 12 * 30 * 24); //formula to calculate age in hours
let agehr = document.createElement('p');
let hrAnswer = document.createTextNode('You are ' + agehours + ' hours old');
agehr.setAttribute('id','ageinhr');
agehr.appendChild(hrAnswer);
document.getElementById('ageinhours').appendChild(agehr);
//console.log('hour success');//display in console
/*................FOR AGE IN MINUTES.......................*/
let ageminute = (ageInyear * 12 * 30 * 24 * 60);
let agemin = document.createElement('p');
let minAnswer = document.createTextNode('You are ' + ageminute + ' minute old');
agemin.setAttribute('id','minuteage');
agemin.appendChild(minAnswer);
document.getElementById('ageinminutes').appendChild(agemin);
//console.log('minute success');
/*................FOR AGE IN SECONDS.......................*/
let agesec = (ageInyear * 12 * 30 * 24 * 60 * 60);
let ageinsec = document.createElement('p');
let secAnswer = document.createTextNode('You are ' + agesec + ' seconds old');
ageinsec.setAttribute('id','secINage');
ageinsec.appendChild(secAnswer);
document.getElementById('ageinsecounds').appendChild(ageinsec);
//console.log('second success');
}
function reset(){
document.getElementById('ageinyears').innerHTML = "<label>age in years :  </label>";
document.getElementById('ageInDays').innerHTML = "<label>age in days :  </label>";
document.getElementById('ageInMonth').innerHTML = "<label>age in month :  </label>";
document.getElementById('ageinhours').innerHTML = "<label>age in hours :  </label>";
document.getElementById('ageinminutes').innerHTML = "<label>age in minutes :  </label>";
document.getElementById('ageinsecounds').innerHTML = "<label>age in secounds :  </label>";
console.log('reset success');
}
*{
margin: 0;
padding: 0;
}
.flex-container{
display: flex;
border: 1px solid black;
padding: 15px;
flex-wrap: wrap;
justify-content: space-around;
flex-direction: row;
}
.flex-container-result div{
margin-top: 2px;
border: 1px solid red;
display: flex;
padding: 10px;
justify-content: center;
}
.flex-container-result label{
font-size: 18px;
font-weight: bold;
text-transform: capitalize;
display: flex;
flex-direction: column;
}
<body>
<div class="container">
<h2>Age Calclator.</h2>
<div class="flex-container">
<div>
<button type="button" class="btn btn-primary mr-5" onclick="ageCalculator()"><b>click me</b></button>
</div>
<div>
<button type="button" class="btn btn-danger mr-4" onclick="reset()"><b>Reset</b></button>
</div>
</div>
<div class="flex-container-result">
<div id="ageinyears">
<label>age in years :  </label>
</div>
<div id="ageInDays">
<label>age in days :  </label>
</div>
<div id="ageInMonth">
<label>age in month :  </label>
</div>
<div id="ageinhours">
<label>age in hours :  </label>
</div>
<div id="ageinminutes">
<label>age in minutes :  </label>
</div>
<div id="ageinsecounds">
<label>age in secounds :  </label>
</div>
</div>
</div>
<script src="proj1.js"></script>
</body>
I'm trying to get the second hand on this clock to sweep smoothly instead of ticking. Also, It would be nice to have a better starting effect, rather than having the image jump to the current time. Finally, any suggestions you have on more efficiently coding this would be appreciated.
I can get the smooth animation by using css only, but didn't know how to use that method and also have a real-time clock. I've also tried to use get.milliSeconds() to increase the resolution of the ticks, but that was a flop.
Also you'll see some weird math where I define hp, mp and sp. I had to do that to turn the hands to 12:00 to start because I didn't think to do that when I was in Photoshop.
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!DOCTYPE html>
<html>
<head>
<title>ClockTester</title>
<script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.4.1.js">
</script>
<script>
function everySecond() {
var currentTime = new Date();
var s = currentTime.getSeconds();
var m = currentTime.getMinutes();
m = m + (s/60);
var h = currentTime.getHours();
h = h + (m/60);
if(h == 24){
h = 0;
}
if(h > 12){
h = h - 12;
}
var hp = ((h+1.75) * 360 / 12);
var mp = ((m+50.5) * 360 / 60) ;
var sp = ((s+23) * 360 /60) ;
$("#seconds").css({
'transform': 'rotate(' + sp + 'deg)'
});
$("#minutes").css({
'transform': 'rotate(' + mp + 'deg)'
});
$("#hours").css({
'transform': 'rotate(' + hp + 'deg)'
});
}
setInterval(everySecond, 1000);
</script>
<style>
.image {
position: absolute;
top: 50%;
left: 50%;
margin:-200px 0 0 -200px;
}
</style>
</head>
<body>
<div>
<img class="image" src="https://66.media.tumblr.com/15b5e223866f9a2d5a592dd1dd31f493/tumblr_ptrh01lYI01v4sne9_540.gif">
<img id="hours" class="image" src="https://66.media.tumblr.com/d315a9c84d38858205671a2d2a5b3126/tumblr_ptrh011jss1v4sne9_540.gif">
<img id="minutes" class="image" src="https://66.media.tumblr.com/8e0cd8682849af842dda19c82c10af9d/tumblr_ptrh01LfWM1v4sne9_540.gif">
<img id="seconds" class="image" src="https://66.media.tumblr.com/9773fc5b2345f553ad49985611c0a916/tumblr_ptrh01TQoo1v4sne9_540.gif">
</div>
</body>
</html>
You could get milliseconds and decrease the interval.
var s = currentTime.getSeconds() + currentTime.getMilliseconds() / 1000;
For starting, you could set the <div> to hidden and activate after setting the first interval.
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!DOCTYPE html>
<html>
<head>
<title>ClockTester</title>
<script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.4.1.js">
</script>
<script>
function everySecond() {
var currentTime = new Date();
var s = currentTime.getSeconds() + currentTime.getMilliseconds() / 1000;
var m = currentTime.getMinutes();
m = m + (s / 60);
var h = currentTime.getHours();
h = h + (m / 60);
if (h == 24) {
h = 0;
}
if (h > 12) {
h = h - 12;
}
var hp = ((h + 1.75) * 360 / 12);
var mp = ((m + 50.5) * 360 / 60);
var sp = ((s + 23) * 360 / 60);
$("#seconds").css({
'transform': 'rotate(' + sp + 'deg)'
});
$("#minutes").css({
'transform': 'rotate(' + mp + 'deg)'
});
$("#hours").css({
'transform': 'rotate(' + hp + 'deg)'
});
}
setInterval(everySecond, 20);
</script>
<style>
.image {
position: absolute;
top: 50%;
left: 50%;
margin: -200px 0 0 -200px;
}
</style>
</head>
<body>
<div>
<img class="image" src="https://66.media.tumblr.com/15b5e223866f9a2d5a592dd1dd31f493/tumblr_ptrh01lYI01v4sne9_540.gif">
<img id="hours" class="image" src="https://66.media.tumblr.com/d315a9c84d38858205671a2d2a5b3126/tumblr_ptrh011jss1v4sne9_540.gif">
<img id="minutes" class="image" src="https://66.media.tumblr.com/8e0cd8682849af842dda19c82c10af9d/tumblr_ptrh01LfWM1v4sne9_540.gif">
<img id="seconds" class="image" src="https://66.media.tumblr.com/9773fc5b2345f553ad49985611c0a916/tumblr_ptrh01TQoo1v4sne9_540.gif">
</div>
</body>
</html>
You can use transition-timing in css:
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!DOCTYPE html>
<html>
<head>
<title>ClockTester</title>
<script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.4.1.js">
</script>
<script>
function everySecond() {
var currentTime = new Date();
var s = currentTime.getSeconds();
var m = currentTime.getMinutes();
m = m + (s/60);
var h = currentTime.getHours();
h = h + (m/60);
if(h == 24){
h = 0;
}
if(h > 12){
h = h - 12;
}
var hp = ((h+1.75) * 360 / 12);
var mp = ((m+50.5) * 360 / 60) ;
var sp = ((s+23) * 360 /60) ;
$("#seconds").css({
'transform': 'rotate(' + sp + 'deg)',
'transition': 'all 0.5s'
});
$("#minutes").css({
'transform': 'rotate(' + mp + 'deg)'
});
$("#hours").css({
'transform': 'rotate(' + hp + 'deg)'
});
}
setInterval(everySecond, 1000);
</script>
<style>
.image {
position: absolute;
top: 50%;
left: 50%;
margin:-200px 0 0 -200px;
}
</style>
</head>
<body>
<div>
<img class="image" src="https://66.media.tumblr.com/15b5e223866f9a2d5a592dd1dd31f493/tumblr_ptrh01lYI01v4sne9_540.gif">
<img id="hours" class="image" src="https://66.media.tumblr.com/d315a9c84d38858205671a2d2a5b3126/tumblr_ptrh011jss1v4sne9_540.gif">
<img id="minutes" class="image" src="https://66.media.tumblr.com/8e0cd8682849af842dda19c82c10af9d/tumblr_ptrh01LfWM1v4sne9_540.gif">
<img id="seconds" class="image" src="https://66.media.tumblr.com/9773fc5b2345f553ad49985611c0a916/tumblr_ptrh01TQoo1v4sne9_540.gif">
</div>
</body>
</html>
I am running several timers on one page. I am uncertain as to how to stop an individual timer when that particular project is complete and still display the timer showing the total time it took to complete.
For instance, if countup2 is completed on January 5, 2019 what/where would be the proper syntax?
HTML
<div class="countup" id="countup1">
<p class="days">00</p>
<p class="timeRefDays">Days</p>
<p class="hours">00</p>
<p class="timeRefHours">hrs</p>
<p class="minutes">00</p>
<p class="timeRefMinutes">min</p>
<p class="seconds">00</p>
<p class="timeRefSeconds">sec</p>
</div>
<div class="countup" id="countup2">
<p class="days">00</p>
<p class="timeRefDays">Days</p>
<p class="hours">00</p>
<p class="timeRefHours">hrs</p>
<p class="minutes">00</p>
<p class="timeRefMinutes">min</p>
<p class="seconds">00</p>
<p class="timeRefSeconds">sec</p>
</div>
<div class="countup" id="countup3">
<p class="days">00</p>
<p class="timeRefDays">Days</p>
<p class="hours">00</p>
<p class="timeRefHours">hrs</p>
<p class="minutes">00</p>
<p class="timeRefMinutes">min</p>
<p class="seconds">00</p>
<p class="timeRefSeconds">sec</p>
</div>
<script>
/*
* Basic Count Up from Date and Time
*/
window.onload = function() {
// Month,Day,Year,Hour,Minute,Second
upTime('jan,01,2018,00:00:00', 'countup1'); // ****** Change this line!
upTime('dec,01,2018,10:10:10', 'countup2'); // ****** Change this line!
upTime('dec,01,2018,10:10:10', 'countup3'); // ****** Change this line!
}
function upTime(countTo, id) {
now = new Date();
countTo = new Date(countTo);
difference = (now - countTo);
days = Math.floor(difference / (60 * 60 * 1000 * 24) * 1);
hours = Math.floor((difference % (60 * 60 * 1000 * 24)) / (60 * 60 *
1000) * 1);
mins = Math.floor(((difference % (60 * 60 * 1000 * 24)) % (60 * 60 *
1000)) / (60 * 1000) * 1);
secs = Math.floor((((difference % (60 * 60 * 1000 * 24)) % (60 * 60 *
1000)) % (60 * 1000)) / 1000 * 1);
idEl = document.getElementById(id);
idEl.getElementsByClassName('days')[0].innerHTML = days;
idEl.getElementsByClassName('hours')[0].innerHTML = hours;
idEl.getElementsByClassName('minutes')[0].innerHTML = mins;
idEl.getElementsByClassName('seconds')[0].innerHTML = secs;
setInterval(function() {
upTime(countTo, id);
}, 1000);
}
</script>
<style>
.countup {
text-align: center;
font-family: verdana;
font-size: 20px;
font-weight: bold;
}
.countup p {
display: inline-block;
padding: 10px;
background: #F94EEE;
margin: 0 0 20px;
border-radius: 3px;
color: white;
min-width: 2.6rem;
}
</style>
I'd take a look at the Date API for some examples on setting up timers.
I am doing a project where I created a countdown timer using JavaScript. It features stop-, start-, and reset buttons.
I want to create a fill effect animation starting from the bottom, based on the countdown timer. I want the fill effect to fill a certain percentage of the circle so that when the countdown reaches 0, the whole circle will be filled.
I want to use vanilla JavaScript. No jQuery or SVG.
Here is my code so far for the basic timer starting with HTML, then CSS and my Javascript code.
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<h1>Pomodoro Clock</h1>
<div class="container">
<div class="row">
<h3>Session Length</h3>
<div class="row button1">
<button type="button" onclick="decreaseTime()">-</button>
<span id="SessionLength">25</span>
<button type="button" onclick="increaseTime()">+</button>
</div>
</div>
<!--My Start/Stop/Reset buttons-->
<div class="row">
<div class="myButtons">
<button type="button" onclick="startTime()">Start</button>
<button type="button" onclick="stopTime()">Stop</button>
<button type="button" onclick="resetTime()">Reset</button>
</div>
</div>
<!--My Circle-->
<div class="row">
<div class="circleDraw">
<h2 class="text-center">Session</h2>
<h1 id="output">25:00</h1>
</div>
</div>
</div>
h1{
text-align: center;
}
h3{
text-align: right;
padding-right: 30%;
}
.myButtons{
text-align: center;
padding-top: 10%;
}
.circleDraw{
border-radius: 50%;
border: 2px solid;
width: 300px;
height: 300px;
margin: 50px auto;
}
.text-center{
text-align: center;
padding: 30px;
}
.txt-center{
text-align: center;
}
.button1{
text-align: right;
padding-right: 35%
}
var time = 1500;
var running = 0;
var myStopID;
var startTime = function(){
running = 1;
if(running == 1){
timer();
}
}
var stopTime = function(){
clearTimeout(myStopID);
running = 0;
}
var resetTime = function(){
if(running == 0){
time = 1500;
}
var min = Math.floor(time / 60);
var sec = time % 60;
min = min < 10 ? "0" + min : min;
sec = sec < 10 ? "0" + sec : sec;
document.getElementById('output').innerHTML= min;
document.getElementById('SessionLength').innerHTML= min;
}
var timer = function(){
if(running == 1){
myStopID = setTimeout(function(){
time--;
var min = Math.floor(time / 60);
var sec = time % 60;
min = min < 10 ? "0" + min : min;
sec = sec < 10 ? "0" + sec : sec;
document.getElementById("output").innerHTML= min + ":" + sec;
timer();
}, 1000);
}
}
function decreaseTime(){
if(time <= 0){
return 0;
}
time = time - 60;
var min = Math.floor(time/60);
document.getElementById('SessionLength').innerHTML= min;
document.getElementById('output').innerHTML= min;
}
function increaseTime(){
if(time >= 5940){
return 5940;
}
time = time + 60;
var min = Math.floor(time/60);
document.getElementById('SessionLength').innerHTML= min;
document.getElementById('output').innerHTML= min;
}
What you have done so far looks good. I'd look at using the canvas element and the arc() method on that to draw the circle and partial fill.
More info here...
https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Drawing_shapes
And basic Canvas and SVG example for drawing a circle in this answer...
https://stackoverflow.com/a/6936351/4322803