(function() {
"use strict";
const alarmAudio = new Audio('alarm.wav');
const labelAlarmSetFor = document.getElementById('time');
let timeoutId = -1;
let intervalId = -1;
const padLeft = (value) => {
while (value.length < 2) {
value = '0' + value;
}
return value;
};
const checkTime = (alarmTime) => {
const now = new Date();
// log to console to show the constant comparisons. remove this line when you can see the wasted processor cycles.
console.log('checking to see if ' + now.toUTCString() + ' is >= to ' + alarmTime.toUTCString());
if (now >= alarmTime) {
// time to sound the alarm
// clear this interval as it's no longer needed
clearInterval(intervalId);
intervalId = -1;
// sound the alarm
soundAlarm();
};
};
const setTimerAsTimeout = (offset) => {
return setTimeout(soundAlarm, offset);
};
const setTimerAsInterval = (alarmTime) => {
return setInterval(() => (checkTime(alarmTime)), 1000);
};
const logAlarmTimeToUser = (alarmDateTime) => {
const monthNames = ["January", "Febuary", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
const dayNames = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
const year = alarmDateTime.getFullYear().toString();
const month = monthNames[alarmDateTime.getMonth()];
const weekday = dayNames[alarmDateTime.getDay()];
const day = padLeft(alarmDateTime.getDate().toString());
const hour = padLeft(alarmDateTime.getHours().toString());
const minute = padLeft(alarmDateTime.getMinutes().toString());
const second = padLeft(alarmDateTime.getSeconds().toString());
const alarmDate = [year, month, day].join('-');
const alarmTime = [hour, minute, second].join(':');
console.log('Alarm will sound at ' + alarmDateTime.toUTCString());
if (labelAlarmSetFor) {
labelAlarmSetFor.innerText = 'Alarm set for ' + alarmTime + ' on ' + weekday + ', ' + alarmDate;
}
};
const getAlarmTime = (ms) => {
const offset = new Date();
offset.setMilliseconds(offset.getMilliseconds() + ms);
return offset;
};
const soundAlarm =() => { // alarmtime and time match start Alarm
console.log('play the sound');
// call to alarmAudio.play(); // assuming that's how it works...
};
const preventPosts = (e) => {
// prevent button clicks (et. al.) from posting.
e.preventDefault();
return false;
};
const stopAlarm = (e) => {
if (timeoutId >= 0) {
// cancel any existing alarms scheduled by timeout
clearTimeout(timeoutId);
}
if (intervalId >= 0) {
// cancel any existing alarms scheduled by interval
clearInterval(intervalId);
}
if (labelAlarmSetFor) {
labelAlarmSetFor.innerText = '';
}
// call to alarmAudio.stop(); // assuming that's how it works...
if (e) {
return preventPosts(e);
}
};
const getElementArray = (selector) => {
return Array.prototype.slice.call(document.querySelectorAll(selector));
};
const getParent = (elem, className) => {
const invalidNodes = /html|body/g
let parent = elem.parentNode ? elem.parentNode : null;
if (parent && !invalidNodes.test(parent.tagName.toLowerCase())) {
if (className) {
if (!parent.classList.contains(className)) {
parent = getParent(parent.parentNode, className)
}
}
} else {
parent = null;
}
return parent;
};
const changeHandler = (e) => {
const isHours = getParent(e.target, 'set-hours') !== null;
const isMinutes = getParent(e.target, 'set-minutes') !== null;
const value = parseInt(e.target.value, 10) || 0;
const factor = isHours ? value * 60 * 60 * 1000 : value * 60 * 1000;
const alarmTime = getAlarmTime(factor);
stopAlarm();
/*
// if setting as a timeout, which involves far less checking of the time (i.e., none... it just schedules the alarm to occur at a specific datetime).
logAlarmTimeToUser(alarmTime);
const now = new Date();
const offset = alarmTime.getTime() - now.getTime();
timeoutId = setTimerAsTimeout(offset);
*/
// or, if setting as an interval to actually compare current system time with the alarm time, which is being done once every second (adjustable in the setTimerAsInterval function).
logAlarmTimeToUser(alarmTime);
intervalId = setTimerAsInterval(alarmTime);
};
const attachChangeHandler =() => {
const hours = getElementArray('.set-hours > input[type="number"]');
const minutes = getElementArray('.set-minutes > input[type="number"]');
const inputs = hours.concat(minutes);
if (!inputs.length) {
setTimeout(attachChangeHandler, 50); // wait another 50ms and try again.
} else {
inputs.forEach((input) => {
input.addEventListener('change', changeHandler, false);
});
}
};
const attachClickHandler =() => {
const button = document.getElementById('cancel-alarm');
if (!button) {
setTimeout(attachClickHandler, 50); // wait another 50ms and try again.
} else {
button.addEventListener('click', stopAlarm, false);
}
};
//TODO: add function to Loop Alarm
//TODO: add function to Reset
attachChangeHandler();
attachClickHandler();
}());
.set-hours, .set-minutes { display: inline-block; }
<div id="set-alarm">
<h2 class="set-alarm-header">Set Alarm</h2>
<label class="set-hours">
<p class="time-setting-hours">Hours</p>
<input type="number" value="0" min="0">
</label>
<label class="set-minutes">
<p class="time-setting-minutes">Minutes</p>
<input type="number" value="0" min="0">
</label>
<button id="cancel-alarm">Cancel Alarm</button>
</div>
<div>
<label id="time"></label>
</div>
Et la question est? – Legends
'if (hour === alarmTime && min === alarmTime)' implique que 'hour' et' min' sont les mêmes, c'est-à-dire '08: 08',' 09: 09', '10: 10', etc. et que 'alarmTime' représente magiquement la valeur de l'heure et la valeur de la minute _simultaneously_ ... Où sont définies vos quatre variables? Nous avons besoin de plus de contexte de votre JavaScript. – Xufox
Vous voudrez probablement setInterval() plutôt que de continuer à définir setTimeout() encore et encore https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setInterval –