I keep on getting Uncaught TypeError: Cannot set property 'innerHTML' of null on the time where it tells u the day, hour, minute. "timeDiv2.innerHTML = 'it\'s ' + today + ' ' + hour + ':' + minutes + suffix + '';" this the one always being error or when it closing time.it changes to the error or stays at the same line. am i writing it correct?
var imgArray = new Array();
imgArray[0] = new Image();
imgArray[0].src = 'http://www.weebly.com/editor/uploads/1/1/3/4/11341626/custom_themes/599346900698327146/files/Gifs/OpenLightOff.png';
imgArray[1] = new Image();
imgArray[1].src = 'http://www.weebly.com/editor/uploads/1/1/3/4/11341626/custom_themes/599346900698327146/files/Gifs/OpenLightOn.gif';
var now = new Date();
var weekday = new Array(7);
weekday[0] = "Sunday";
weekday[1] = "Monday";
weekday[2] = "Tuesday";
weekday[3] = "Wednesday";
weekday[4] = "Thursday";
weekday[5] = "Friday";
weekday[6] = "Saturday";
var today = weekday[now.getDay()];
var dayOfWeek = now.getDay();
var hour = now.getHours();
var minutes = now.getMinutes();
var suffix = hour >= 12 ? "PM" : "AM";
var checkTime2 = function() {
var timeDiv2 = document.getElementById('timeDiv2');
//add AM or PM
// add 0 to one digit minutes
if (minutes < 10) {
minutes = "0" + minutes
};
if ((dayOfWeek == 1 || dayOfWeek == 2 || dayOfWeek == 3 || dayOfWeek == 4 || dayOfWeek == 0 ) && hour >= 6 && hour <= 21) {
hour = ((hour + 11) % 12 + 1); //i.e. show 1:15 instead of 13:15
timeDiv2.innerHTML = 'it\'s ' + today + ' ' + hour + ':' + minutes + suffix + '<br><center><img style="width:100%;top:0px;border-radius:10px;" src= '+imgArray[1].src+'></center>';
timeDiv2.className = 'open';
}
else if ((dayOfWeek == 5 || dayOfWeek == 6) && hour >= 6 && hour <= 22){
hour = ((hour + 11) % 12 + 1);
timeDiv2.innerHTML = 'it\'s ' + today + ' ' + hour + ':' + minutes + suffix + '<br><center><img style="width:100%;top:0px;border-radius:10px;" src= '+imgArray[1].src+'></center>';
timeDiv2.className = 'open';
}
else {
if (hour == 0 || hour > 5) {
hour = ((hour + 11) % 12 + 1); //i.e. show 1:15 instead of 13:15
}
timeDiv2.innerHTML = 'It\'s ' + today + ' ' + hour + ':' + minutes + suffix + '<br><center><img style="width:100%;top:0px;border-radius:10px;" src= '+imgArray[0].src+' ></center>';
timeDiv2.className = 'closed';
}
};
var currentDay = weekday[now.getDay()];
var currentDayID = "." + currentDay; //gets todays weekday and turns it into id
$(currentDayID).toggleClass("today"); //hightlights today in the view hours modal popup
checkTime2();
[id ^="timeDiv"]
{
width:100%;
background: transparent;
margin: 0 auto;
border-radius: 3px;
/* -webkit-box-shadow: 0 8px 16px -8px #adadad;
-moz-box-shadow: 0 8px 16px -8px #adadad;
box-shadow: 0 8px 16px -8px #adadad;*/
display:block;
background-color: rgb(0,0,0); /* Fallback color */
background-color: rgba(0,0,0,0.5); /* Black w/ opacity */
}
.day {
display: inline-block;
float: left;
}
.time {
display: inline-block;
float: right
}
.today {
color: rgb(200, 85, 39);
font-weight: 600;
}
.closed {
color: rgba(231, 76, 60, 0.85);
}
.open {
position:relative;
color: #27ae60;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.2.3/jquery.min.js"></script>
<div id="timeDiv2"></div>
Since the timeDiv2 element is part of your DOM, the best chance is that you run the javascript code before the HTML is being completely loaded.
You can fix this by calling the checkTime2() function only once the page has completely loaded:
$(function() {
checkTime2();
});
You are attempting you manipulate your DOM before it has loaded, try one of the following.
1.
Load your script as the last part of your body.
2.
Use the DOMContentLoaded event.
document.addEventListener('DOMContentLoaded', function () {
/** Your code here... **/
});
The DOMContentLoaded event is fired when the initial HTML document has been completely loaded and parsed, without waiting for stylesheets, images, and subframes to finish loading. A very different event load should be used only to detect a fully-loaded page. It is an incredibly popular mistake to use load where DOMContentLoaded would be much more appropriate, so be cautious.
3.
If you are using jQuery then,
$(document).ready(function () {
/** Your code here... **/
});
Related
how can I differentiate when I have to use HEX code and color name? and also how can I change my background color? I mean, I think I have changed my background color to black, but when I embed it to my Notion page, it still comes up with aliceblue color, not black. anyone can help me to add time?
var weekday = new Array(7);
weekday[0] = "Sunday";
weekday[1] = "Monday";
weekday[2] = "Tuesday";
weekday[3] = "Wednesday";
weekday[4] = "Thursday";
weekday[5] = "Friday";
weekday[6] = "Saturday";
var today = new Date();
var hrs = today.getHours();
var dayOfWeek = weekday[today.getDay()];
var date = dayOfWeek + " " + today.getDate() + "/" + (today.getMonth() + 1) + '/' + today.getFullYear();
var greet;
if (hrs < 12)
greet = 'Good Morning ';
else if (hrs >= 12 && hrs <= 17)
greet = 'Good Afternoon ';
else if (hrs >= 17 && hrs <= 18)
greet = ' Good Evening ';
else if (hrs >= 18 && hrs <= 24)
greet = 'Good Night ';
document.getElementById('lbl').innerHTML =
greet += "Ivan" + `<div id="date"> It's ${date}</div>`;
#lbl {
font-family: monospace;
font-size: xx-large;
color: #F0F8FF;
padding: 5px;
text-align: center;
line-height: 1.5;
height: 85%
}
#date {
font-size: large;
}
body {
background-color: black;
}
<div id="lbl"></div>
I'm trying to a make a live clock using JS Date();
It seems freeze, until, I refresh the page.
var today = new Date();
var date = today.getFullYear() + '-' + (today.getMonth() + 1) + '-' + today.getDate();
var time = today.getHours() + ":" + today.getMinutes() + ":" + today.getSeconds();
var dateTime = date;
setInterval(function() {
document.getElementById('clock1').innerHTML = dateTime;
document.getElementById('clock2').innerHTML = dateTime;
document.getElementById('clock3').innerHTML = dateTime;
document.getElementById('clock4').innerHTML = dateTime;
document.getElementById('clock5').innerHTML = dateTime;
}, 1000)
var span = document.getElementsByClassName('time');
function time() {
var d = new Date();
var s = d.getSeconds();
var m = d.getMinutes();
var h = d.getHours();
span.textContent = h + ":" + m + ":" + s;
}
setInterval(time, 1000);
#font-face {
font-family: "DOTMBold";
src: url("DOTMBold.TTF");
}
#font-face {
font-family: "LLPIXEL3";
src: url("LLPIXEL3.ttf");
}
#font-face {
font-family: "Technology";
src: url("Technology.ttf");
}
#font-face {
font-family: "The Led Display St";
src: url("The Led Display St.ttf");
}
#clock1 {
font-family: "Calculator";
font-size: 70px;
}
#clock2 {
font-family: "DOTMBold";
font-size: 70px;
}
#clock3 {
font-family: "LLPIXEL3";
font-size: 70px;
}
#clock4 {
font-family: "Technology";
font-size: 70px;
}
#clock5 {
font-family: "The Led Display St";
font-size: 70px;
}
<title>hw18</title>
<div id="clock1"><span class="time"></span></div>
<div id="clock2"><span class="time"></span></div>
<div id="clock3"><span class="time"></span></div>
<div id="clock4"><span class="time"></span></div>
<div id="clock5"><span class="time"></span></div>
Several issues
document.getElementsByClassName('time'); is plural. It returns a collection. You need to loop over the span - but the spans are gone when you change the clockX innerHTML
You do not add the time to the dateTime
You likely want to pad the digits
You need to make a new date object for every call.
You likely want to do the following:
extract the time into its own function
pad the digits
now the spans are no longer needed but can be reinstated if necessary
const pad = num => ("0" + num).slice(-2)
const getTime = function() {
var today = new Date();
return `${today.getFullYear()}-${pad(today.getMonth() + 1)}-${pad(today.getDate())}
${pad(today.getHours())}:${pad(today.getMinutes())}:${pad(today.getSeconds())}`;
}
setInterval(function() {
var dateTime = getTime()
document.getElementById('clock1').innerHTML = dateTime;
document.getElementById('clock2').innerHTML = dateTime;
document.getElementById('clock3').innerHTML = dateTime;
document.getElementById('clock4').innerHTML = dateTime;
document.getElementById('clock5').innerHTML = dateTime;
}, 1000)
#font-face {
font-family: "DOTMBold";
src: url("DOTMBold.TTF");
}
#font-face {
font-family: "LLPIXEL3";
src: url("LLPIXEL3.ttf");
}
#font-face {
font-family: "Technology";
src: url("Technology.ttf");
}
#font-face {
font-family: "The Led Display St";
src: url("The Led Display St.ttf");
}
#clock1 {
font-family: "Calculator";
font-size: 70px;
}
#clock2 {
font-family: "DOTMBold";
font-size: 70px;
}
#clock3 {
font-family: "LLPIXEL3";
font-size: 70px;
}
#clock4 {
font-family: "Technology";
font-size: 70px;
}
#clock5 {
font-family: "The Led Display St";
font-size: 70px;
}
<title>hw18</title>
<div id="clock1"></div>
<div id="clock2"></div>
<div id="clock3"></div>
<div id="clock4"></div>
<div id="clock5"></div>
You just need to move your date creation inside the interval. With your current solution, it will take the current date on startup and put it into the html every 1 second. But still the same date.
Here is a possible solution solution:
setInterval(function() {
// Just move your date creation inside the interval function
var today = new Date();
var date = today.getFullYear() + '-' + (today.getMonth() + 1) + '-' + today.getDate();
var time = today.getHours() + ":" + today.getMinutes() + ":" + today.getSeconds();
var dateTime = date + " " + time; // Add the time to the date string
// Now it will take the current date and put it in all html elements
document.getElementById('clock1').innerHTML = dateTime;
document.getElementById('clock2').innerHTML = dateTime;
document.getElementById('clock3').innerHTML = dateTime;
document.getElementById('clock4').innerHTML = dateTime;
document.getElementById('clock5').innerHTML = dateTime;
}, 1000);
The issue is that your variable var time is overwriting the function time() so then the setInterval is using the wrong value for the first parameter.
Rename the function
function updateTime() {
var d = new Date();
var s = d.getSeconds();
var m = d.getMinutes();
var h = d.getHours();
span.textContent = h + ":" + m + ":" + s;
}
setInterval(updateTime, 1000);
I'm currently working on a project that will display the amount of time left in a certain time period based on the users current time. Here is the code.
var periods = [
[ '07:45' , '08:34' ],
[ '08:38' , '09:30' ],
[ '09:34' , '10:23' ],
[ '10:27' , '11:16' ],
[ '11:20' , '12:38' ],
[ '12:42' , '15:55' ],
[ '07:00' , ]
];
updateTimePeriods();
setInterval(updateTimePeriods, 1000); // Update every second
function updateTimePeriods() {
var listEl = document.getElementById('periods');
var now = new Date();
var count = periods.length;
listEl.innerHTML='';
for (var i = 0; i < count; i++) {
if(formatTimeRemaining(timeLeft(now, periods[i][1])).charAt(0)!='–') {
child=listEl.appendChild(document.createElement('LI'));
child.innerHTML = periods[i][0] + ' — ' + periods[i][1]
+ ' => Duration: ' + formatUTCTime(duration(periods[i][0], periods[i][1]))
+ ', Remaining: ' + formatTimeRemaining(timeLeft(now, periods[i][1]));
}
}
}
function duration(start, end) {
var startTime = parseTime(start);
var endTime = parseTime(end);
return endTime.getTime() - startTime.getTime();
}
function timeLeft(now, end) {
var nowTime = parseTime(formatTime(now));
var endTime = parseTime(end);
return endTime.getTime() - nowTime.getTime();
}
function parseTime(timeStr) {
var tokens = timeStr.split(':');
return new Date(1970, 0, 1, parseInt(tokens[0], 10), parseInt(tokens[1], 10));
}
function formatUTCTime(time) {
var date = new Date(time);
return padZero(date.getUTCHours()) + ':' + padZero(date.getUTCMinutes());
}
function formatTime(time) {
var date = new Date(time);
return padZero(date.getHours()) + ':' + padZero(date.getMinutes());
}
function formatTimeRemaining(time) {
var sign = '+';
if (time < 0) { time *= -1; sign = '–'; }
var date = new Date(time);
return sign + padZero(date.getUTCHours()) + ':' + padZero(date.getUTCMinutes()) + ':' + padZero(date.getUTCSeconds());
}
function padZero(n) { return ('00' + n).substr(-2); }
body {
background-color: #A00000;
background-size: cover;
margin: 0;
padding: 0;
}
.outer-box {
border: 3px solid black;
height: true;
width: 75%;
padding: 10px;
margin: 10px auto 10px auto;
border-radius: 10px;
background-color: white;
text-align:center;
}
#periods {
border-radius: 5px;
margin: 20px auto 20px auto;
padding: 5px;
font-weight: bold;
text-align: center;
list-style-type: none;
}
<div class="outer-box">
<ul id="periods"></ul>
</div>
My goal is only display to the user the amount of time left in the current time period instead of all of them. And if its in between a time period it shows the amount of time until the next one occurs. The issue is once all the times occur I need to tell him much time until the start of the next time which occurs on a different day. To elaborate, currently if all the time periods occur it displays a blank space because there is nothing to display and all the times are negative. I want to display the amount of time until the next days starting time.
You should break the for loop as you create the new LI element. This way it should only show the actual time period.
for (var i = 0; i < count; i++) {
if(formatTimeRemaining(timeLeft(now, periods[i][1])).charAt(0)!='–') {
child=listEl.appendChild(document.createElement('LI'));
child.innerHTML = periods[i][0] + ' — ' + periods[i][1]
+ ' => Duration: ' + formatUTCTime(duration(periods[i][0], periods[i][1]))
+ ', Remaining: ' + formatTimeRemaining(timeLeft(now, periods[i][1]));
break;
}
}
I'm struggling to figure out how Date() works, I found this on the web and wanted to make a countdown that stops at 21:57 UTC Time. It currently displays the message at 21:00 and apears until 22:00.
I tried to add if(currenthours != 21 && currentminutes >= 57){ and always broke it and got the message. I want it to stop 3 minutes before 22:00 and display the message. After it gets to 22:00 restart the countdown for the next day at 21:57.
Any help will be greatly appreciated !
var date;
var display = document.getElementById('time');
setInterval(function(){
date = new Date( );
var currenthours = date.getUTCHours();
// alert(currenthours);
var currentminutes = date.getUTCMinutes();
// alert(currentminutes);
var hours;
var minutes;
var secondes;
if (currenthours != 21) {
if (currenthours < 21) {
hours = 20 - currenthours;
} else {
hours = 21 + (24 - currenthours);
}
minutes = 60 - date.getUTCMinutes();
secondes = 60 - date.getUTCSeconds();
display.innerHTML = ('00' + hours).slice(-2) + ' HOURS ' + '<p>' +
('00' + minutes).slice(-2) + ' MINUTES ' + '</p>' +
('00' + secondes).slice(-2) + ' SECONDS';
} else {
display.innerHTML = "IT'S 21:57";
}
},1000);
<div id='time'></div>
Made a fiddle
https://jsfiddle.net/5qrs0tcp/1/
This is what I ended up with :
/*
|================================|
| COUNTDOWN TIMER |
|================================|
*/
// Return the UTC time component of a date in h:mm:ss.sss format
if (!Date.prototype.toISOTime) {
Date.prototype.toISOTime = function() {
return this.getUTCHours() + ':' +
('0' + this.getUTCMinutes()).slice(-2) + ':' +
('0' + this.getUTCSeconds()).slice(-2);
}
}
// Return the difference in time between two dates
// in h:mm:ss.sss format
if (!Date.prototype.timeDiff) {
Date.prototype.timeDiff = function(date2) {
var diff = Math.abs(this - date2);
return timeobj = {
hours : (diff/3.6e6|0), // hours
minutes : ('0' + ((diff%3.6e6)/6e4|0)).slice(-2), // minutes
seconds : ('0' + ((diff%6e4)/1e3|0)).slice(-2) // seconds
}
}
}
function countDown() {
var now = new Date();
var limitHr = 19;
var limitMin = 55;
var limitDate = new Date(+now);
// Set limitDate to next limit time
limitDate.setUTCHours(limitHr, limitMin, 0, 0);
// var msg = ['Currently: ' + now.toISOTime() + '<br>' + 'Limit: ' + limitDate.toISOTime()];
var msg = [];
var diff;
// If outside limitHr:limitMin to (limitHr + 1):00
if (now.getUTCHours() == limitHr && now.getUTCMinutes() >= limitMin) {
msg.push('Countdown stopped');
setTimeout(function(){
msg = ['Wait for it'];
var jsonCounter = {
stats : msg
}
jsonfile.writeFileSync(DailyGamePath, jsonCounter, {spaces: 3});
},5000);
var jsonCounter = {
stats : msg
}
jsonfile.writeFileSync(DailyGamePath, jsonCounter, {spaces: 3});
} else {
if (now > limitDate) limitDate.setDate(limitDate.getDate() + 1);
var jsonCounter = {
hours : now.timeDiff(limitDate).hours,
minutes : now.timeDiff(limitDate).minutes,
seconds : now.timeDiff(limitDate).seconds,
validating : msg
}
jsonfile.writeFileSync(DailyGamePath, jsonCounter, {spaces: 3});
}
}
setInterval(countDown, 1000);
var daily_status;
setTimeout( function(){
setInterval( function() {
jsonfile.readFile(DailyGamePath, (err, obj) => {
daily_status={
hours: obj.hours,
minutes: obj.minutes,
seconds: obj.seconds,
stats: obj.stats,
validating: obj.validating
};
return daily_status;
});
}, 1000);
}, 3000);
setTimeout( function(){
io.sockets.on('connection', (socket) => {
setInterval( function() {
// var GameStatus=DailyGameStatus();
socket.broadcast.emit('stream', {hours:daily_status.hours, minutes:daily_status.minutes, seconds:daily_status.seconds, stats:daily_status.stats, validating:daily_status.validating});
}, 1000);
});
}, 3000);
Date objects are very simple, they're just a time value and some handy methods.
I think your logic just needs to be:
if (currenthours != 21 && currentminutes < 57) {
// set the out of hours message
} else {
// time is from 21:57 to 21:59 inclusive
}
The countdown doesn't quite work because you're counting to 00 not to 57, but otherwise there doesn't seem to be an issue.
var date;
var display = document.getElementById('time');
setInterval(function(){
date = new Date( );
var currenthours = date.getUTCHours();
var currentminutes = date.getUTCMinutes();
var hours;
var minutes;
var secondes;
var limitHr = 5; // Change these to required values
var limitMin = 02; // Using 5:12 for convenience
var message = 'Currently: ' + date.toISOString() + '<p>';
// Create new message if outside limitHr:limitMin to limitHr:59 inclusive
if (currenthours != limitHr || currentminutes < limitMin) {
if (currenthours <= limitHr) {
hours = limitHr - currenthours;
} else {
hours = limitHr + (24 - currenthours);
}
minutes = limitMin - date.getUTCMinutes();
minutes += minutes < 0? 60 : 0;
secondes = 60 - date.getUTCSeconds();
message += ('00' + hours).slice(-2) + ' HOURS ' + '<p>' +
('00' + minutes).slice(-2) + ' MINUTES ' + '</p>' +
('00' + secondes).slice(-2) + ' SECONDS';
} else {
message += 'It\'s on or after ' + limitHr + ':' +
('0'+limitMin).slice(-2) + ' GMT';
}
// Display the message
display.innerHTML = message;
},1000);
<div id="time"></div>
Yes, the timer has issues but that wasn't part of the question. For a counter, it's simpler to just work in time differences, so I've added some methods to Date.prototype for ISO time (to be consistent with ISO Date) and time difference, then use those functions.
The function builds a Date for the end time so that calculations can use Date methods.
// Return the UTC time component of a date in h:mm:ss.sss format
if (!Date.prototype.toISOTime) {
Date.prototype.toISOTime = function() {
return this.getUTCHours() + ':' +
('0' + this.getUTCMinutes()).slice(-2) + ':' +
('0' + this.getUTCSeconds()).slice(-2) + '.' +
('00' + this.getUTCMilliseconds()).slice(-3) + 'Z';
}
}
// Return the difference in time between two dates
// in h:mm:ss.sss format
if (!Date.prototype.timeDiff) {
Date.prototype.timeDiff = function(date2) {
var diff = Math.abs(this - date2);
var sign = this > date2? '+' : '-';
return sign + (diff/3.6e6|0) + ':' + // hours
('0' + ((diff%3.6e6)/6e4|0)).slice(-2) + ':' + // minutes
('0' + ((diff%6e4)/1e3|0)).slice(-2) + '.' + // seconds
('00' + (diff%1e3)).slice(-3); // milliseconds
}
}
function countDown() {
var now = new Date();
var limitHr = 1;
var limitMin = 10;
var limitDate = new Date(+now);
// Set limitDate to next limit time
limitDate.setUTCHours(limitHr, limitMin, 0, 0);
var msg = ['Currently: ' + now.toISOTime() + '<br>' + 'Limit: ' + limitDate.toISOTime()];
var diff;
// If outside limitHr:limitMin to (limitHr + 1):00
if (now.getUTCHours() != limitHr || now.getUTCMinutes() != limitMin) {
if (now > limitDate) limitDate.setDate(limitDate.getDate() + 1);
msg.push(now.timeDiff(limitDate));
} else {
msg.push('It\'s after ' + limitHr + ':' + ('0'+limitMin).slice(-2));
}
document.getElementById('msgDiv2').innerHTML = msg.join('<br>');
}
window.onload = function() {
setInterval(countDown, 1000);
}
<div id="msgDiv2"></div>>
I've left the milliseconds in, round to seconds if you wish.
I've left the timer using setInterval, though I'd prefer to use setTimeout and manually calculate the time to just after the next full second so that it never skips. Most browsers using setTimeout will slowly drift so that they skip a second every now and then. Not really an issue unless you happen to see it, or compare it to the tick of the system clock.
I'm working on a personal trainer website that lets you choose the time of your training session. There are 6 times available: 5 mins, 10 mins, 15 mins, and so on. This is what I have so far.
I want to highlight the time that you've chosen. I've only tried to implement this for the top row of times, and when you click a time to highlight it the other ones don't get unhighlighted, but that is not why I'm asking this question. My problem is that when you click on a time, nothing happens. I've tried looking in the console and this is the error it throws:
What's wrong with my code?
$("body").append(
"<p class='text' id='CYTText'>Choose your session's time:</p>"
);
setUpCYT(350, 200, 0.8, 0.85);
function setUpCYT(littleXOffset, littleYOffset, littleScale, littleOpacity) {
for (i = 1; i < 4; i++) {
var timeSelectorElement = "[data='" + i + "']";
var timeSelectorName = "timeSelector"+i;
$("body").append(
"<p class='text' id='CYTTimerText' data='" + i + "' onclick='selectTime(" + timeSelectorElement + ")'>00:00</p>"
);
$("[data='" + i + "']").css({"left":littleXOffset * (i-2), "-webkit-transform":"scale(" + littleScale + ")", "opacity":littleOpacity});
timeSelectorName = new Timer(timeSelectorElement);
timeSelectorName.set(i*5,0);
}
for (i = 1; i < 4; i++) {
$("body").append(
"<p class='text' id='CYTTimerText' data='" + i+3 + "'>00:00</p>"
);
$("[data='" + i+3 + "']").css({"top":littleYOffset, "left":littleXOffset * (i-2), "-webkit-transform":"scale(" + littleScale + ")", "opacity":littleOpacity});
var timeSelectorElement = "[data='" + i+3 + "']";
var timeSelectorName = "timeSelector"+i+3;
timeSelectorName = new Timer(timeSelectorElement);
timeSelectorName.set((i+3)*5,0);
}
//select the middle
selectTime("[data='2']");
}
function selectTime(data) {
TweenLite.to($(data), 0.5, {
"-webkit-transform":"scale(1)",
"opacity":1
});
}
//timer function
function Timer (element) {
var minutes, seconds, finalTimeInSeconds, displayMinutes, displaySeconds, interval = 1000, self = this, timeLeftToNextSecond = 1000, running = false;
this.set = function(inputMinutes, inputSeconds) {
finalTimeInSeconds = inputMinutes * 60 + inputSeconds;
minutes = (Math.floor(finalTimeInSeconds / 60));
seconds = finalTimeInSeconds % 60;
this.print();
}
this.add = function(inputMinutes, inputSeconds) {
finalTimeInSeconds += inputMinutes * 60 + inputSeconds;
finalTimeInSeconds = (finalTimeInSeconds < 0) ? 0 : finalTimeInSeconds;
minutes = (Math.floor(finalTimeInSeconds / 60));
seconds = finalTimeInSeconds % 60;
this.print();
}
this.subtract = function(inputMinutes, inputSeconds) {
finalTimeInSeconds -= inputMinutes * 60 + inputSeconds;
if(finalTimeInSeconds < 0) {nextTask()}
finalTimeInSeconds = (finalTimeInSeconds < 0) ? 0 : finalTimeInSeconds;
minutes = (Math.floor(finalTimeInSeconds / 60));
seconds = finalTimeInSeconds % 60;
this.print();
}
this.reset = function() {
this.set(0,0);
}
this.print = function() {
displayMinutes = (minutes.toString().length == 1) ? "0" + minutes : minutes; //ternary operator: adds a zero to the beggining
displaySeconds = (seconds.toString().length == 1) ? "0" + seconds : seconds; //of the number if it has only one caracter.
$(element).text(displayMinutes + ":" + displaySeconds);
}
this.run = function() {
if (running == false) {
running = true;
var _f = function() {
secondStarted = new Date;
self.subtract(0, 1);
interval = 1000;
var theColorIs = $(element).css("color");
ac = setTimeout(_f,interval);
}
ac = setTimeout(_f, interval);
}
}
this.stop = function() {
if (running == true) {
running = false;
stopped = new Date;
interval = 1000 - (stopped - secondStarted);
clearTimeout(ac);
}
}
}
body{
background-color: #02BFC1;
overflow:hidden;
margin: 0;
}
#font-face {
font-family: 'Bebas Neue';
font-style: normal;
font-weight: normal;
src: local('Bebas Neue'), url('BebasNeue.woff') format('woff');
}
.text {
color: #F1F2F0;
font-family:Bebas Neue;
-webkit-user-select: none;
cursor: default;
text-shadow: 3px 3px 2px rgba(0,0,0,0.2);
}
#CYTText {
text-align:center;
height: 100px;
position: absolute;
margin: auto;
top: 0;
bottom: 290px;
right: 0;
left: 0;
font-size:50px;
}
#CYTTimerText {
text-align:center;
height: 100px;
position: absolute;
margin: auto;
top: 0;
bottom: 150px;
right: 0;
left: 0;
font-size:95px;
}
The syntax error is caused by the string that you're passing to append():
$("body").append(
"<p class='text' id='CYTTimerText' data='" + i +
"' onclick='selectTime(" + timeSelectorElement + ")'>00:00</p>"
);
Let's print an instance of this string and examine it:
<p class='text' id='CYTTimerText' data='1' onclick='selectTime([data='1'])'>00:00</p>
Observe that the onclick handler is a code fragment delimited by single quotes:
onclick='selectTime([data='
We can fix this by replacing the single quotes with escaped double quotes:
$("body").append(
"<p class='text' id='CYTTimerText' data='" + i +
"' onclick=\"selectTime(" + timeSelectorElement + ")\">00:00</p>"
);
However, now we have another problem. An instance of the string looks like this:
<p class='text' id='CYTTimerText' data='1' onclick="selectTime([data='1'])">00:00</p>
The code for onclick is selectTime([data='1']), which is syntactically incorrect. The intention is to pass the string "[data='1']" to selectTime.
The inline HTML already uses double quotes to delimit the onclick value. How do we put double quotes inside this value? We have to use " for each double quote:
$("body").append(
"<p class='text' id='CYTTimerText' data='" + i + "' onclick=\"selectTime("" + timeSelectorElement + "")\">00:00</p>"
);
Now an instance of the string looks like this:
<p class='text' id='CYTTimerText' data='1' onclick="selectTime("[data='1']")">00:00</p>
That looks strange, but it will be correct once it has been inserted into the document.
After making that change, the code sort of works. It's still not right because you have layout problems, but at least you can click on the 15:00 time and see that the onclick handler calls selectTime correctly.
By the way, there are better approaches than building that complicated string. You can simplify the inline handler to onclick="selectTime(this)", where this will have the value of the object that was clicked. An even better way to go about it would be to avoid inline handler definitions. Instead, build a paragraph object and make a new function that you assign as a click handler.
Regardless of how you implement the onclick handler, you're left with the problem of overlapping timer elements. Your timers are paragraphs that you've absolutely positioned next to one another. The paragraphs stretch as wide as possible. Thus, the first timer is obscured by subsequent timers.
You can get rid of the overlap by displaying the timers as inline-block elements. To restrict the width of the layout, put everything into a wrapper div. The following snippet demonstrates this approach.
window.onload = function () {
$('#wrapTimers').append(
"<p class='text' id='CYTText'>Choose your session duration:</p>"
);
setUpCYT(350, 200, 0.8, 0.85);
};
function setUpCYT(littleXOffset, littleYOffset, littleScale, littleOpacity) {
for (i = 1; i < 4; i++) {
var timeSelectorElement = "[data='" + i + "']";
var timeSelectorName = "timeSelector"+i;
var s = "<p class='text timerContainer' data='" + i +
"' onclick=\"selectTime(this)\">00:00</p>";
//"' onclick=\"selectTime("" + timeSelectorElement + "")\">00:00</p>";
$('#wrapTimers').append(s);
$("[data='" + i + "']").css({"left":littleXOffset * (i-2), "-webkit-transform":"scale(" + littleScale + ")", "opacity":littleOpacity});
timeSelectorName = new Timer(timeSelectorElement);
timeSelectorName.set(i*5,0);
}
for (i = 1; i < 4; i++) {
$('#wrapTimers').append(
"<p class='text timerContainer' data='" + i+3 + "'>00:00</p>"
);
$("[data='" + i+3 + "']").css({"top":littleYOffset, "left":littleXOffset * (i-2), "-webkit-transform":"scale(" + littleScale + ")", "opacity":littleOpacity});
var timeSelectorElement = "[data='" + i+3 + "']";
var timeSelectorName = "timeSelector"+i+3;
timeSelectorName = new Timer(timeSelectorElement);
timeSelectorName.set((i+3)*5,0);
}
//select the middle
selectTime("[data='2']");
}
function selectTime(selector) {
TweenLite.to($(selector), 0.5, {
"-webkit-transform":"scale(1)",
"opacity":1
});
}
//timer function
function Timer (element) {
var minutes, seconds, finalTimeInSeconds, displayMinutes, displaySeconds, interval = 1000, self = this, timeLeftToNextSecond = 1000, running = false;
this.set = function(inputMinutes, inputSeconds) {
finalTimeInSeconds = inputMinutes * 60 + inputSeconds;
minutes = (Math.floor(finalTimeInSeconds / 60));
seconds = finalTimeInSeconds % 60;
this.print();
}
this.add = function(inputMinutes, inputSeconds) {
finalTimeInSeconds += inputMinutes * 60 + inputSeconds;
finalTimeInSeconds = (finalTimeInSeconds < 0) ? 0 : finalTimeInSeconds;
minutes = (Math.floor(finalTimeInSeconds / 60));
seconds = finalTimeInSeconds % 60;
this.print();
}
this.subtract = function(inputMinutes, inputSeconds) {
finalTimeInSeconds -= inputMinutes * 60 + inputSeconds;
if(finalTimeInSeconds < 0) {nextTask()}
finalTimeInSeconds = (finalTimeInSeconds < 0) ? 0 : finalTimeInSeconds;
minutes = (Math.floor(finalTimeInSeconds / 60));
seconds = finalTimeInSeconds % 60;
this.print();
}
this.reset = function() {
this.set(0,0);
}
this.print = function() {
displayMinutes = (minutes.toString().length == 1) ? "0" + minutes : minutes; //ternary operator: adds a zero to the beggining
displaySeconds = (seconds.toString().length == 1) ? "0" + seconds : seconds; //of the number if it has only one caracter.
$(element).text(displayMinutes + ":" + displaySeconds);
}
this.run = function() {
if (running == false) {
running = true;
var _f = function() {
secondStarted = new Date;
self.subtract(0, 1);
interval = 1000;
var theColorIs = $(element).css("color");
ac = setTimeout(_f,interval);
}
ac = setTimeout(_f, interval);
}
}
this.stop = function() {
if (running == true) {
running = false;
stopped = new Date;
interval = 1000 - (stopped - secondStarted);
clearTimeout(ac);
}
}
}
body {
background-color: #02BFC1;
overflow: hidden;
margin: 0;
}
#wrapTimers {
width: 800px;
margin: 40px auto;
text-align: center;
}
.text {
color: #F1F2F0;
font-family: Oswald, sans-serif;
-webkit-user-select: none;
cursor: default;
text-shadow: 3px 3px 2px rgba(0, 0, 0, 0.2);
}
#CYTText {
width: 800px;
margin: auto;
font-size: 50px;
}
.timerContainer {
text-align: center;
display: inline-block;
font-size: 95px;
margin: 0 10px;
}
<link rel="stylesheet" type="text/css"
href="https://fonts.googleapis.com/css?family=Oswald" >
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/gsap/latest/TweenLite.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/gsap/latest/plugins/CSSPlugin.min.js"></script>
<div id="wrapTimers"></div>
There are a couple of simple issues. first off the string isn't being parsed correctly that is setting up the onclick
Closing quotes
It should look like this: onclick="selectTime("[data='2']")"
But it looks like this: onclick="selectTime([data=" 2'])'
Reference Error
There is also a scoping /reference error for the function selectTime the click is trying to call
Here is the full working example: http://jsfiddle.net/qLnLmgy6/2/
Hope that helps!