JavaScriptで今度は「通知機能付きのタイマー」を作りました。
https://notification.atukan.com
前回と同じく一応ソースコードも残しておきますね
JavaScript
__________________
class HourlyNotifier {
constructor(soundUrl = 'https://www.soundjay.com/buttons/beep-01a.mp3') {
this.soundUrl = soundUrl;
this.audio = new Audio(this.soundUrl);
this.interval = null;
this.countdownInterval = null;
this.timeout = null;
this.notificationIntervalMinutes = 60;
this.statusElement = document.getElementById('status');
this.countdownElement = document.getElementById('countdown');
this.intervalInput = document.getElementById('intervalInput');
this.requestNotificationPermission();
this.setupKeyboardShortcuts();
}
async requestNotificationPermission() {
if ("Notification" in window) {
const permission = await Notification.requestPermission();
if (permission !== "granted") {
alert("通知が許可されていません。ブラウザの設定を確認してください。");
}
}
}
notify() {
this.audio.play().catch(err => console.log("音声再生エラー:", err));
if ("Notification" in window && Notification.permission === "granted") {
new Notification("時間のお知らせ", {
body: `現在の時刻: ${new Date().toLocaleTimeString('ja-JP')}`,
icon: "https://via.placeholder.com/32"
});
}
alert(`時間のお知らせ\n現在の時刻: ${new Date().toLocaleTimeString('ja-JP')}`);
}
updateStatus(message) {
if (this.statusElement) {
this.statusElement.textContent = message;
}
}
updateCountdown() {
if (!this.nextNotificationTime) return;
const now = new Date();
const timeLeftMs = this.nextNotificationTime - now;
if (timeLeftMs <= 0) return;
const minutesLeft = Math.floor(timeLeftMs / (1000 * 60));
const secondsLeft = Math.floor((timeLeftMs % (1000 * 60)) / 1000);
if (this.countdownElement) {
this.countdownElement.textContent = `次の通知まで: ${minutesLeft}分 ${secondsLeft}秒`;
}
}
setInterval(minutes) {
const parsedMinutes = parseInt(minutes, 10);
if (isNaN(parsedMinutes) || parsedMinutes <= 0) {
alert("有効な分数を入力してください(1以上の整数)");
return false;
}
this.notificationIntervalMinutes = parsedMinutes;
return true;
}
start() {
if (this.interval) return;
const inputValue = this.intervalInput ? this.intervalInput.value : this.notificationIntervalMinutes;
if (!this.setInterval(inputValue)) return;
const intervalMs = this.notificationIntervalMinutes * 60 * 1000;
this.nextNotificationTime = new Date(Date.now() + intervalMs);
this.updateStatus(`通知: 開始 (${this.notificationIntervalMinutes}分間隔)`);
this.timeout = setTimeout(() => {
this.notify();
this.nextNotificationTime = new Date(Date.now() + intervalMs);
this.interval = setInterval(() => {
this.notify();
this.nextNotificationTime = new Date(Date.now() + intervalMs);
}, intervalMs);
}, intervalMs);
this.updateCountdown();
this.countdownInterval = setInterval(() => this.updateCountdown(), 1000);
}
stop() {
if (this.timeout) {
clearTimeout(this.timeout);
this.timeout = null;
}
if (this.interval) {
clearInterval(this.interval);
this.interval = null;
}
if (this.countdownInterval) {
clearInterval(this.countdownInterval);
this.countdownInterval = null;
this.nextNotificationTime = null;
if (this.countdownElement) {
this.countdownElement.textContent = "次の通知まで: -";
}
}
this.updateStatus("通知: 停止");
}
setupKeyboardShortcuts() {
document.addEventListener('keydown', (event) => {
// Ctrl + N で開始
if (event.ctrlKey && event.key === 'n') {
event.preventDefault();
this.start();
}
// Ctrl + Q で停止
if (event.ctrlKey && event.key === 'q') {
event.preventDefault();
this.stop();
}
});
}
}
const notifier = new HourlyNotifier();______________________
HTML
______________________
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>カスタム通知タイマー</title>
<style>
body {
font-family: Arial, sans-serif;
text-align: center;
margin-top: 50px;
}
button, input {
padding: 10px 20px;
margin: 5px;
}
#status, #countdown {
margin: 10px;
font-size: 1.2em;
}
#shortcuts {
margin: 10px;
color: #555;
}
</style>
</head>
<body>
<div id="status">通知: 停止</div>
<div id="countdown">次の通知まで: -</div>
<input type="number" id="intervalInput" placeholder="通知間隔(分)" min="1" value="60">
<button onclick="notifier.start()">通知開始</button>
<button onclick="notifier.stop()">通知停止</button>
<div id="shortcuts">ショートカット: [Ctrl + N] で開始, [Ctrl + Q] で停止</div>
<script src="your-script.js"></script>
</body>
</html> __________________________________ HTMLとは別に外部からJavaScriptを読み込ませる形で組んでいます。
0 件のコメント:
コメントを投稿