首页 > 解决方案 > 当来自“背景 > 脚本”的脚本试图清除它时,“web_accessible_resources”脚本设置的间隔 ID 没有被清除

问题描述

我制作了一个 Chrome 扩展,其中 abc.js 从 manifest.json 的“web_accessible_resources”字段运行。我已经在全局范围内声明了一个名为“var autoScrollStatus”的变量。我用零初始化它,但最终将一个 setInterval ID 存储到其中。

在某一时刻,我必须从“var autoScrollStatus”中清除这个 setIntervalID。因此,包含代码的 def.js 文件(从 manifest.json 中的背景>脚本启动)clearInterval(autoScrollStatus);会运行,但是当它到达这一行时,def.js 会因主题错误而崩溃。

但是如果我clearInterval(autoScrollStatus);在 Chrome DevTools 中运行,它运行得很好。更重要的是,如果我delete window.autoScrollStatus;在 def.js 中提到,它也运行没有任何错误。这显然意味着范围在这里不是问题,那么为什么只有在尝试清除 setInterval() ID 时它仍然会抛出 ReferenceError 呢?

关于这里发生了什么的任何想法?谢谢!

编辑 - 这些是我正在使用的脚本:

这是 abc.ts:

var asSpeeds = {1: 250, 2: 150, 3: 100, 4: 90, 5: 75, 6: 60, 7: 50, 8: 40, 9: 30};
var chordsTA:HTMLTextAreaElement = document.querySelector("#chordsTA");
var asBtn:HTMLButtonElement = document.querySelector("#asBtn");
var autoScrollSpeed = 250;
var autoScrollStatus = 0;

function toggleAutoScroll() {
    if(autoScrollStatus){
        clearInterval(autoScrollStatus);
        autoScrollStatus = 0;
        console.log("Stopped autoscroll.");
        return;
    }
    
    autoScrollStatus = setInterval(_=>{chordsTA.scrollBy(0, 1)}, autoScrollSpeed);
    console.log("Started autoscroll.")
}

var speedUpAS = () => {
    console.log("Speeding upppppppppppppppppppp")
    let asBtnText = asBtn.getAttribute('data-front');
    let newSpeed:number = parseInt(asBtnText.charAt(asBtnText.length - 1))+1;
    if (newSpeed in asSpeeds){
        clearInterval(autoScrollStatus);
        autoScrollStatus = 0;
        autoScrollStatus = setInterval(_=>{chordsTA.scrollBy(0, 1)}, autoScrollSpeed);
    }
}

var speedDnAS = () => {
    console.log("Speeding downnnnnnnnnnnnnnnnnn")
    let asBtnText = asBtn.getAttribute('data-front');
    let newSpeed:number = parseInt(asBtnText.charAt(asBtnText.length - 1))-1;
    if (newSpeed in asSpeeds){
        clearInterval(autoScrollStatus);
        autoScrollStatus = 0;
        autoScrollStatus = setInterval(_=>{chordsTA.scrollBy(0, 1)}, autoScrollSpeed);
    }
}

这是def.ts:

console.log("deactivating extension");
clearInterval(autoScrollStatus);

在 def.ts 中,我还尝试了 console.logging autoScrollStatus 和 abc.ts 文件中定义的其他全局变量,但每个变量都得到一个 ReferenceError,这意味着肯定存在范围问题(我已更正)。关于解决这个问题的任何建议?我可以毫无问题地访问 Chrome DevTools 中的那些全局变量。

manifest.json 也是这样的:

{
    "name": "YouTube Overlay",
    "version": "0.1",
    "manifest_version" : 2,
    "description": "Lays overlay on YouTube, can be used for chords/lyrics.",
    "background" : {
      "scripts" : ["bg.js"]
    },
    "permissions": ["activeTab"],
    "browser_action": {},
    "web_accessible_resources": ["abc.js"]
  }

这是 bg.js:(基本上它使图标充当我的扩展程序的打开/关闭切换)

let enable=false;
chrome.browserAction.onClicked.addListener(function (tab) {
    enable = enable ? false : true;
    if(enable){
    //turn on...
        chrome.tabs.executeScript(null, { file: 'ghi.js' }); 
    }else{
    //turn off...
        chrome.tabs.executeScript(null, { file: 'def.js' }); 
    }
});

标签: javascriptgoogle-chromegoogle-chrome-extensionscope

解决方案


这是一个范围问题。由 abc.ts 初始化的全局变量(从 web_accessible_resources 初始化)对 def.ts 不可见(从 background>scripts 初始化)。因此,我没有尝试从 abc.ts 中清除 intervalID(在每次退出时),而是修改了我的 abc.ts 以清除 intervalID(在每次初始化时),以便清除之前剩余的任何 IntervalID,如果不存在,它也不会抛出任何错误。这是新的 abc.ts:

clearInterval(autoScrollStatus) // no need to use try...catch as weirdly doesn't throw any error on first run!

// rest of the code same as in my question

var asSpeeds = {1: 250, 2: 150, 3: 100, 4: 90, 5: 75, 6: 60, 7: 50, 8: 40, 9: 30};
var chordsTA:HTMLTextAreaElement = document.querySelector("#chordsTA");
var asBtn:HTMLButtonElement = document.querySelector("#asBtn");
var autoScrollSpeed = 250;
var autoScrollStatus = 0;

推荐阅读