Chrome计时器扩展程序-即使关闭扩展程序也如何保持计时器运行?

时间:2019-09-27 10:39:14

标签: javascript google-chrome-extension timer storage

我正在做我的第一个扩展程序-下午茶定时器。选择茶类型/输入分钟数后,计时器将开始运行。问题是,当我更改选项卡或关闭扩展名时,计时器将停止运行,尽管我希望它在后台运行。我不确定如何使用 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()]
      }
    ]);
  });
});

谢谢大家!

2 个答案:

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