问题描述
我在 Tampermonkey 脚本中使用以下代码。
function scriptMain () {
setTimeout(function(){
GM_notification ( {
title: 'Refresh Business Manager',text: 'Your about to be logged out of staging,click here to refresh your login.',image: 'https://i.stack.imgur.com/geLPT.png',onclick: () => {
console.log ("My notice was clicked.");
location.reload();
}
} );
},5*1000);
console.log ("Script main code ran.");
}
每当浏览器选项卡打开超过 5 秒时,代码都会显示通知,其中包含一个用于刷新当前浏览器选项卡的按钮。我想使用这个脚本每 20 分钟左右提醒我一次,浏览器中的登录名之一即将自动注销。
该功能按预期工作,但如果我从我登录的站点打开 5 个选项卡,我将在页面即将用完时收到 5 个通知。我希望能够从 Tampermonkey 脚本中判断此脚本是否已在另一个选项卡上运行,不执行或仅能显示一次通知。
我一直在查看有关以下赠款的 Tampermonkey 文档:
GM_getTab(callback)
GM_saveTab(tab)
GM_getTabs(callback)
但我似乎无法确定此功能是否可行。
解决方法
在符合现代规范的浏览器上,您可以在用户脚本中使用 BroadcastChannel 与同一域中的其他标签进行通信。使超时稍微随机 - 添加或减去几秒钟以允许所有打开的选项卡进行协调。发送通知时,还要在 BroadcastChannel 中发送一条消息,告诉用户脚本的其他实例也重置它们的计时器。
const channel = new BroadcastChannel('logout-notify');
let timeoutId;
function makeTimeout() {
clearTimeout(timeoutId);
timeoutId = setTimeout(function () {
GM_notification({
title: 'Refresh Business Manager',text: 'Your about to be logged out of staging,click here to refresh your login.',image: 'https://i.stack.imgur.com/geLPT.png',onclick: () => {
console.log("My notice was clicked.");
location.reload();
}
});
channel.postMessage('notified');
},1000 * 60 * 20 + (Math.random() * 10000)); // 20 minutes plus up to 10 seconds
}
// When below runs,another tab created a notification
// reset the timeout for this tab,schedule another one for 20ish minutes from now
channel.onmessage = makeTimeout;
// initialize timeout on pageload?
makeTimeout();
此代码将导致警报最多每 20 分钟显示一次。如果您关闭正在处理的一个选项卡,其他选项卡将不间断地填补空白。