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 网上商店允许它没有任何问题。