Chrome 分机 |多个警报同时响起
Chrome Extension | Multiple alarms going off at once
我正在创建任务提醒扩展。用户可以选择继续添加任务并为每个任务设置提醒。
我正在使用 chrome.storage 来存储这些任务,并在存储上使用 onChanged 侦听器为添加到存储中的每个任务创建警报。
但问题是,如果我为一项任务设置 2 分钟的提醒,为另一项任务设置 3 分钟的提醒。然后在 2 分钟结束时,我收到了这两个任务的通知,在 3 分钟结束时,我再次收到了这两个任务的通知。
background.js
chrome.storage.onChanged.addListener(function(changes, namespace) {
let id = (changes.tasks.newValue.length)-1
let data = changes.tasks.newValue[id]
if(data.task && data.hrs && data.min){
let totalMins = (parseInt(data.hrs*60))+parseInt(data.min)
let alarmTime = 60*1000*totalMins
chrome.alarms.create("remind"+id,{when:Date.now() + alarmTime})
}
chrome.alarms.onAlarm.addListener(()=>{
let notifObj = {
type: "basic",
iconUrl:"./images/logo5.png",
title: "Time to complete you task",
message: data.task
}
chrome.notifications.create('remindNotif'+id, notifObj)
})
popup.js
let hrs = document.querySelector("#time-hrs")
let min = document.querySelector("#time-min")
let submitBtn = document.querySelector("#submitBtn")
let task = document.querySelector("#task")
hrs.value = 0;
min.value = 1
hrs.addEventListener('change',()=>{
if (hrs.value < 0){
hrs.value =0;
}
})
min.addEventListener('change',()=>{
if (min.value < 1){
min.value = 1;
}
})
submitBtn.addEventListener("click", ()=>{
if(task.value){
chrome.storage.sync.get('tasks',(item)=>{
let taskArr = item.tasks ? item.tasks : []
linkArr.push({task:task.value, hrs:hrs.value, min:min.value})
chrome.storage.sync.set({ 'tasks' : taskArr })
})
};
});
manifest.json
{
"name" : "Link Snooze",
"description" : "This extension reminds you to open your saved links",
"manifest_version":2,
"version":"0.1.0",
"icons":{
"16":"./images/logo5.png",
"48":"./images/logo5.png",
"128":"./images/logo5.png"
},
"browser_action":{
"default_popup":"popup.html",
"default_icon":"./images/logo5.png"
},
"permissions":["storage", "notifications","alarms"],
"background" : {
"scripts": ["background.js"],
"persistent" : false
},
"options_page":"options.html"
}
问题。
除了旧的侦听器之外,当存储发生变化时,您还注册了一个新的 onAlarms
侦听器。每次触发一个警报时全部 运行。
解决方案。
使用非持久性后台脚本时,所有 API 侦听器必须为同一功能只注册一次,并且必须同步完成,而不是在异步回调或 await
或 then()
,否则当后台脚本自动终止然后为该事件唤醒时,该事件将丢失。惯例是在脚本的开头执行此操作。到目前为止,它对您有用的原因是,当弹出窗口打开或后台脚本的开发工具打开时,后台脚本保持活动状态。
这样的监听器显然不能像在代码中 data.task
那样直接使用异步回调中的变量。解决方案是使用不同的方法将数据附加到事件,例如,使用已经包含数据的 name
创建警报,特别是 data.task
.
chrome.alarms.create(data.task, {delayInMinutes: hrs * 60 + min});
onAlarm
事件提供警报作为参数,因此您可以使用其 name
,请参阅 documentation。
随机提示:
创建对象时调用JSON.stringify(obj),在[=18=中调用JSON.parse(alarm.name),对象可以作为报警名].
在弹出窗口中,不要手动调整超出范围的值,而是使用 html:
中输入的数字
<input id="time-min" type=number min=0 max=59 step=1>
然后读为数字:document.querySelector("#time-min").valueAsNumber || 0
我正在创建任务提醒扩展。用户可以选择继续添加任务并为每个任务设置提醒。 我正在使用 chrome.storage 来存储这些任务,并在存储上使用 onChanged 侦听器为添加到存储中的每个任务创建警报。 但问题是,如果我为一项任务设置 2 分钟的提醒,为另一项任务设置 3 分钟的提醒。然后在 2 分钟结束时,我收到了这两个任务的通知,在 3 分钟结束时,我再次收到了这两个任务的通知。
background.js
chrome.storage.onChanged.addListener(function(changes, namespace) {
let id = (changes.tasks.newValue.length)-1
let data = changes.tasks.newValue[id]
if(data.task && data.hrs && data.min){
let totalMins = (parseInt(data.hrs*60))+parseInt(data.min)
let alarmTime = 60*1000*totalMins
chrome.alarms.create("remind"+id,{when:Date.now() + alarmTime})
}
chrome.alarms.onAlarm.addListener(()=>{
let notifObj = {
type: "basic",
iconUrl:"./images/logo5.png",
title: "Time to complete you task",
message: data.task
}
chrome.notifications.create('remindNotif'+id, notifObj)
})
popup.js
let hrs = document.querySelector("#time-hrs")
let min = document.querySelector("#time-min")
let submitBtn = document.querySelector("#submitBtn")
let task = document.querySelector("#task")
hrs.value = 0;
min.value = 1
hrs.addEventListener('change',()=>{
if (hrs.value < 0){
hrs.value =0;
}
})
min.addEventListener('change',()=>{
if (min.value < 1){
min.value = 1;
}
})
submitBtn.addEventListener("click", ()=>{
if(task.value){
chrome.storage.sync.get('tasks',(item)=>{
let taskArr = item.tasks ? item.tasks : []
linkArr.push({task:task.value, hrs:hrs.value, min:min.value})
chrome.storage.sync.set({ 'tasks' : taskArr })
})
};
});
manifest.json
{
"name" : "Link Snooze",
"description" : "This extension reminds you to open your saved links",
"manifest_version":2,
"version":"0.1.0",
"icons":{
"16":"./images/logo5.png",
"48":"./images/logo5.png",
"128":"./images/logo5.png"
},
"browser_action":{
"default_popup":"popup.html",
"default_icon":"./images/logo5.png"
},
"permissions":["storage", "notifications","alarms"],
"background" : {
"scripts": ["background.js"],
"persistent" : false
},
"options_page":"options.html"
}
问题。
除了旧的侦听器之外,当存储发生变化时,您还注册了一个新的 onAlarms
侦听器。每次触发一个警报时全部 运行。
解决方案。
使用非持久性后台脚本时,所有 API 侦听器必须为同一功能只注册一次,并且必须同步完成,而不是在异步回调或 await
或 then()
,否则当后台脚本自动终止然后为该事件唤醒时,该事件将丢失。惯例是在脚本的开头执行此操作。到目前为止,它对您有用的原因是,当弹出窗口打开或后台脚本的开发工具打开时,后台脚本保持活动状态。
这样的监听器显然不能像在代码中 data.task
那样直接使用异步回调中的变量。解决方案是使用不同的方法将数据附加到事件,例如,使用已经包含数据的 name
创建警报,特别是 data.task
.
chrome.alarms.create(data.task, {delayInMinutes: hrs * 60 + min});
onAlarm
事件提供警报作为参数,因此您可以使用其 name
,请参阅 documentation。
随机提示:
创建对象时调用JSON.stringify(obj),在[=18=中调用JSON.parse(alarm.name),对象可以作为报警名].
在弹出窗口中,不要手动调整超出范围的值,而是使用 html:
中输入的数字<input id="time-min" type=number min=0 max=59 step=1>
然后读为数字:
document.querySelector("#time-min").valueAsNumber || 0