javascript 切换 chrome 扩展

javascript toggle in chrome extension

我正在创建一个小扩展,只是为了向当前选项卡添加简单的样式

// Called when the user clicks on the browser action.
chrome.browserAction.onClicked.addListener(function(tab) {
  // No tabs or host permissions needed!
  chrome.tabs.executeScript({
    code: "var flag; console.log(flag); if(flag !== 1){window.document.styleSheets[0].insertRule('html{font-size: 10px;}'); flag = 1} else{window.document.styleSheets[0].removeRule('html{font-size: 16px;}'); flag = 0;}"
  });
});

效果很好,为了创建一个 切换 我写了这个逻辑:

var flag;
console.log(flag);
if (flag !== 1) {
  window.document.styleSheets[0].insertRule('html{font-size: 10px;}');
  flag = 1
} else {
  window.document.styleSheets[0].removeRule('html{font-size: 16px;}');
  flag = 0;
}

第一次点击按钮时,标志值为未定义

我的问题:这个toggle有没有更好的写法?

executeScript 具有误导性 - 它 将脚本插入 页面并运行它,它不只是在页面上执行该代码。因此,您将插入脚本的多个副本。很难说该页面将如何处理您的脚本的多个副本,它至少应该抱怨该标志已定义。

但是,如果您接受可能会插入多个副本,但这并不特别重要,那么您应该这样做,以便可以预测标志状态:

window.flag = window.flag || false;
flag = !flag; // toggle - note window scope is implicit
if (flag) {
    // do flag == true stuff
} else {
    // do flag == false stuff
}

通过显式引用 window 对象,您可以添加一个 属性 而无需声明它,它将默认为 false。该行执行了多少次也无关紧要。

向 window 对象添加多个变量通常被认为是不好的做法,您应该为它命名一个永远不会与任何其他变量冲突的名称 - 即不是标志! 话虽如此,创建一个唯一变量作为命名空间是一种常见的做法,例如

window.bhansa = window.bhansa || {myFlag: false, myOtherVariable: 12345};

如果 bhansa 不存在,那么将创建它,您可以安全地定义函数并将变量添加为该对象的属性,而不必担心冲突:

bhansa.myFunction = function() {
}
bhansa.myFilename = "xxx"

我认为实现您想要做的事情的最好方法是使用 Chrome 的 Tabs API and Storage API

chrome.tabs.onCreated.addListener(function(tab) {        
    chrome.storage.get({"bhansa": "NOT_FOUND"}, function(store){
       var bhansa = false;
       if (store["bhansa"] || store["bhansa"] == "NOT_FOUND") {
           bhansa = true;
           chrome.storage.set({"bhansa": !bhansa});
       }
       if (bhansa) {
          chrome.tabs.insertCss(tab.id , {code : "html.... " } ,
              function() {
                  console.log("Done adding styles."); 
              }
          );
       }
    }            
});

希望这能解决您的问题。