即使脚本在多个选项卡上运行,也只运行一次通知脚本

问题描述

我在 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 分钟显示一次。如果您关闭正在处理的一个选项卡,其他选项卡将不间断地填补空白。