Chrome 定时器扩展 - 如何在扩展关闭时保持定时器 运行?
Chrome timer extension - how to keep timer running even when extension is closed?
我正在开发我的第一个扩展 - 下午茶计时器。选择茶后 type/entering 分钟计时器将启动 运行ning。问题是,当我更改选项卡或关闭扩展程序时,计时器将停止 运行ning,尽管我希望它在后台停止 运行。我不确定如何使用 chrome.storage.
来处理这个问题
这是我的timer.js:
function timer(seconds) {
clearInterval(countdown);
const now = Date.now();
const then = now + seconds * 1000;
displayTimeLeft(seconds);
displayEndTime(then);
countdown = setInterval(() => {
const secondsLeft = Math.round((then - Date.now()) / 1000);
if (secondsLeft < 0) {
clearInterval(countdown);
const soundEffect = new Audio("tibetan.mp3");
soundEffect.play();
setTimeout(function() {
alert("Your tea is ready!");
}, 500);
return;
}
displayTimeLeft(secondsLeft);
}, 1000);
}
function displayTimeLeft(seconds) {
const minutes = Math.floor(seconds / 60);
const remainderSeconds = seconds % 60;
const display = `${minutes}:${
remainderSeconds < 10 ? "0" : ""
}${remainderSeconds}`;
if (timerDisplay) {
timerDisplay.textContent = display;
}
//console.log({ minutes, remainderSeconds });
}
function startTimer() {
const seconds = parseInt(this.dataset.time);
console.log(seconds);
timer(seconds);
}
buttons.forEach(button => button.addEventListener("click", startTimer));
background.js
chrome.runtime.onInstalled.addListener(function() {
chrome.declarativeContent.onPageChanged.removeRules(undefined, function() {
chrome.declarativeContent.onPageChanged.addRules([
{
conditions: [new chrome.declarativeContent.PageStateMatcher({})],
actions: [new chrome.declarativeContent.ShowAction()]
}
]);
});
});
提前谢谢大家!
由于 time.js 是弹出窗口 window 的一部分,该文件中的代码(以及您使用setInterval
) 将在弹出 window 关闭后立即停止 运行。
为了使此工作正常,您必须将间隔移动到后台页面,后台页面的上下文可以设置为只要浏览器打开就保持打开状态。
顺便说一句,目前在 background.js 中的代码没有做任何事情,如果你想使用 page actions
这是我的做法:
background.js
let timerID;
let timerTime;
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
if (request.cmd === 'START_TIMER') {
timerTime = new Date(request.when);
timerID = setTimeout(() => {
// the time is app, alert the user.
}, timerTime.getTime() - Date.now());
} else if (request.cmd === 'GET_TIME') {
sendResponse({ time: timerTime });
}
});
timer.js
// Call this when the pop-up is shown
chrome.runtime.sendMessage({ cmd: 'GET_TIME' }, response => {
if (response.time) {
const time = new Date(response.time);
startTimer(time)
}
});
functions startTimer(time) {
if (time.getTime() > Date.now()) {
setInterval(() => {
// display the remaining time
}, 1000)
}
}
function startTime(time) {
chrome.runtime.sendMessage({ cmd: 'START_TIMER', when: time });
startTimer(time);
}
本质上,当用户启动计时器时,您会向后台脚本发送一条消息,其中包含计时器完成的未来日期。然后,在后台脚本中,您设置了在该日期触发的超时,这样即使弹出窗口 window 已关闭,您也可以执行某些操作(播放声音)。
然后,当弹出窗口 window 重新打开时,您向后台脚本发送一条消息,它会发回先前设置的计时器的日期。
这可以改进,目前,只要浏览器在整个计时器的长度内打开,这将正常工作,即使浏览器关闭并重新打开也能正常工作,您可以保存和恢复计时器的存储日期。
将 setInterval() 代码移至后台脚本并将清单中后台脚本的 "Persistent" 属性 更改为 "True"
即使扩展程序的弹出 window 关闭,这允许扩展程序继续 运行 宁后台脚本并且 setInterval() 将继续 运行。
注意:将 "Persistent" 属性 更改为 "True" 时应小心。确保 chrome 网上商店允许它没有任何问题。
我正在开发我的第一个扩展 - 下午茶计时器。选择茶后 type/entering 分钟计时器将启动 运行ning。问题是,当我更改选项卡或关闭扩展程序时,计时器将停止 运行ning,尽管我希望它在后台停止 运行。我不确定如何使用 chrome.storage.
来处理这个问题这是我的timer.js:
function timer(seconds) {
clearInterval(countdown);
const now = Date.now();
const then = now + seconds * 1000;
displayTimeLeft(seconds);
displayEndTime(then);
countdown = setInterval(() => {
const secondsLeft = Math.round((then - Date.now()) / 1000);
if (secondsLeft < 0) {
clearInterval(countdown);
const soundEffect = new Audio("tibetan.mp3");
soundEffect.play();
setTimeout(function() {
alert("Your tea is ready!");
}, 500);
return;
}
displayTimeLeft(secondsLeft);
}, 1000);
}
function displayTimeLeft(seconds) {
const minutes = Math.floor(seconds / 60);
const remainderSeconds = seconds % 60;
const display = `${minutes}:${
remainderSeconds < 10 ? "0" : ""
}${remainderSeconds}`;
if (timerDisplay) {
timerDisplay.textContent = display;
}
//console.log({ minutes, remainderSeconds });
}
function startTimer() {
const seconds = parseInt(this.dataset.time);
console.log(seconds);
timer(seconds);
}
buttons.forEach(button => button.addEventListener("click", startTimer));
background.js
chrome.runtime.onInstalled.addListener(function() {
chrome.declarativeContent.onPageChanged.removeRules(undefined, function() {
chrome.declarativeContent.onPageChanged.addRules([
{
conditions: [new chrome.declarativeContent.PageStateMatcher({})],
actions: [new chrome.declarativeContent.ShowAction()]
}
]);
});
});
提前谢谢大家!
由于 time.js 是弹出窗口 window 的一部分,该文件中的代码(以及您使用setInterval
) 将在弹出 window 关闭后立即停止 运行。
为了使此工作正常,您必须将间隔移动到后台页面,后台页面的上下文可以设置为只要浏览器打开就保持打开状态。
顺便说一句,目前在 background.js 中的代码没有做任何事情,如果你想使用 page actions
这是我的做法:
background.js
let timerID;
let timerTime;
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
if (request.cmd === 'START_TIMER') {
timerTime = new Date(request.when);
timerID = setTimeout(() => {
// the time is app, alert the user.
}, timerTime.getTime() - Date.now());
} else if (request.cmd === 'GET_TIME') {
sendResponse({ time: timerTime });
}
});
timer.js
// Call this when the pop-up is shown
chrome.runtime.sendMessage({ cmd: 'GET_TIME' }, response => {
if (response.time) {
const time = new Date(response.time);
startTimer(time)
}
});
functions startTimer(time) {
if (time.getTime() > Date.now()) {
setInterval(() => {
// display the remaining time
}, 1000)
}
}
function startTime(time) {
chrome.runtime.sendMessage({ cmd: 'START_TIMER', when: time });
startTimer(time);
}
本质上,当用户启动计时器时,您会向后台脚本发送一条消息,其中包含计时器完成的未来日期。然后,在后台脚本中,您设置了在该日期触发的超时,这样即使弹出窗口 window 已关闭,您也可以执行某些操作(播放声音)。 然后,当弹出窗口 window 重新打开时,您向后台脚本发送一条消息,它会发回先前设置的计时器的日期。
这可以改进,目前,只要浏览器在整个计时器的长度内打开,这将正常工作,即使浏览器关闭并重新打开也能正常工作,您可以保存和恢复计时器的存储日期。
将 setInterval() 代码移至后台脚本并将清单中后台脚本的 "Persistent" 属性 更改为 "True"
即使扩展程序的弹出 window 关闭,这允许扩展程序继续 运行 宁后台脚本并且 setInterval() 将继续 运行。
注意:将 "Persistent" 属性 更改为 "True" 时应小心。确保 chrome 网上商店允许它没有任何问题。