我正在做我的第一个扩展程序-下午茶定时器。选择茶类型/输入分钟数后,计时器将开始运行。问题是,当我更改选项卡或关闭扩展名时,计时器将停止运行,尽管我希望它在后台运行。我不确定如何使用 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()]
}
]);
});
});
谢谢大家!
答案 0 :(得分:0)
由于 time.js 是弹出窗口的一部分,因此该文件中的代码(以及您使用setInterval
设置的间隔)将立即停止运行当弹出窗口关闭时。
要执行此操作,您必须将间隔移到背景页面,可以将背景页面的上下文设置为只要打开浏览器就保持打开状态。
顺便说一句, 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);
}
从本质上讲,当用户启动计时器时,您会将带有计时器完成日期的将来日期的消息发送到后台脚本。然后,在后台脚本中,将超时设置为在该日期触发,这样即使关闭了弹出窗口,您也可以执行某些操作(播放声音)。 然后,当重新打开弹出窗口时,您会向后台脚本发送一条消息,它将回传先前设置的计时器的日期。
此问题可以改进,目前,只要在整个计时器长度内打开浏览器,它都可以正常工作,即使关闭并重新打开浏览器,它也可以正常工作,您可以保存和还原计时器的存储的日期。
答案 1 :(得分:0)
将setInterval()代码移动到后台脚本,并将清单中后台脚本的“ Persistent”属性更改为“ True”
即使扩展程序的弹出窗口关闭并且setInterval()将继续运行,这也允许扩展程序继续运行后台脚本。
注意:将“ Persistent”属性更改为“ True”时,请务必小心。确保chrome网站商店允许它没有任何问题。