记住状态 chrome 扩展

2023-12-14

我使用 chrome 扩展来触发两个内容脚本来注入 css。如果用户打开页面,则 contentscript-on.js 加载(在我的 manifest.json 中定义):

清单.json

{
    "name": "tools",
    "version": "1.1",
    "description": "tools",
    "browser_action": {
        "default_icon": "icon-on.png",
        "default_title": "tools"
    },
    "manifest_version": 2,
    "content_scripts": [
        {
            "matches": [ "*://*/*" ],
            "include_globs": [ "*://app.example.*/*" ],
            "js": ["jquery-1.11.0.min.js", "contentscript-on.js"]
        }
    ],
    "background": {
        "scripts": ["background.js"],
        "persistent": true
    },
    "permissions": [
        "storage",
        "https://*.app.example.de/*", "tabs", "webNavigation"
    ]   
}

背景.js

function getToggle(callback) { // expects function(value){...}
  chrome.storage.local.get('toggle', function(data){
    if(data.toggle === undefined) {
      callback(true); // default value
    } else {
      callback(data.toggle);
    }
  });
}

function setToggle(value, callback){ // expects function(){...}
  chrome.storage.local.set({toggle : value}, function(){
    if(chrome.runtime.lastError) {
      throw Error(chrome.runtime.lastError);
    } else {
      callback();
    }
  });
}

chrome.browserAction.onClicked.addListener( function(tab) {
  getToggle(function(toggle){
    toggle = !toggle;
    setToggle(toggle, function(){
      if(toggle){
    //change the icon after pushed the icon to On
    chrome.browserAction.setIcon({path: "icon-on.png", tabId:tab.id});
    //start the content script to hide dashboard
    chrome.tabs.executeScript({file:"contentscript-on.js"});
  }
  else{

    //change the icon after pushed the icon to Off
    chrome.browserAction.setIcon({path: "icon-off.png", tabId:tab.id});
    //start the content script to hide dashboard
    chrome.tabs.executeScript({file:"contentscript-off.js"});
  }
    });
  });
});  

内容脚本-on.js

$(document).ready(function() {

    chrome.storage.local.get('toggle', function(data) {
        if (data.toggle === false) {
            return;
        } else {
            // do some css inject
        }
    });

});

内容脚本-off.js

$(document).ready(function() {
  // set css to original 
});

一切正常,但如何保存图标的“状态”?如果用户关闭浏览器并再次打开它,则应加载上次使用的内容脚本。

非常感谢您的帮助。


你有两种方法(至少),一种是“旧”,一种是“新”。

  1. Old: localStorage

    您的扩展页面有一个共同点localStorage您可以读/写的对象,并且它通过浏览器重新启动而持久存在。

    使用它是同步的:

    var toggle;
    if(localStorage.toggle === undefined){
      localStorage.toggle = true;
    }
    toggle = localStorage.toggle;
    
    chrome.browserAction.onClicked.addListener( function(tab) {
      var toggle = !toggle;
      localStorage.toggle = toggle;
      /* The rest of your code; at this point toggle is saved */
    });
    

    它使用起来很简单,但也有缺点:localStorage内容脚本的上下文不同,因此它们需要通过消息传递从后台脚本获取值;此外,如果在隐身模式下使用扩展程序,也会出现复杂情况。

  2. New: chrome.storage API

    要使用新方法,您需要获得许可"storage"在清单中(不生成警告)。

    另外,与localStorage,使用它是异步的,即您将需要使用回调:

    function getToggle(callback) { // expects function(value){...}
      chrome.storage.local.get('toggle', function(data){
        if(data.toggle === undefined) {
          callback(true); // default value
        } else {
          callback(data.toggle);
        }
      });
    }
    
    function setToggle(value, callback){ // expects function(){...}
      chrome.storage.local.set({toggle : value}, function(){
        if(chrome.runtime.lastError) {
          throw Error(chrome.runtime.lastError);
        } else {
          callback();
        }
      });
    }
    
    chrome.browserAction.onClicked.addListener( function(tab) {
      getToggle(function(toggle){
        toggle = !toggle;
        setToggle(toggle, function(){
          /* The rest of your code; at this point toggle is saved */
        });
      });
    });
    

    异步代码使用起来有点困难,但是您可以获得一些优势。即,内容脚本可以使用chrome.storage您可以直接观察变化,而不是与家长沟通onChanged,你可以使用chrome.storage.sync代替(或一起)chrome.storage.local将更改传播到用户登录的所有浏览器。

EDIT

我提供了一个完整的解决方案,因为 OP 犯了混合每个选项卡状态和全局状态的错误。

内容脚本.js

$(document).ready(function() {
  chrome.storage.local.get('toggle', function(data) {
    if (data.toggle === false) {
      return;
    } else {
      /* do some css inject */
    }
  });

  chrome.storage.onChanged.addListener(function(changes, areaName){
    if(areaName == "local" && changes.toggle) { 
      if(changes.toggle.newValue) {
        /* do some css inject */
      } else {
        /* set css to original */
      }
    }
  });
});

背景.js:

    /* getToggle, setToggle as above */

    function setIcon(value){
      var path = (value)?"icon-on.png":"icon-off.png";
      chrome.browserAction.setIcon({path: path});
    }

    getToggle(setIcon); // Initial state

    chrome.browserAction.onClicked.addListener( function(tab) {
      getToggle(function(toggle){
        setToggle(!toggle, function(){
          setIcon(!toggle);
        });
      });
    });

这样,您只需要一个内容脚本。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

记住状态 chrome 扩展 的相关文章

  • 如何使用 JavaScript 创建链接?

    我有一个标题字符串和一个链接字符串 我不知道如何将两者放在一起以使用 JavaScript 在页面上创建链接 任何帮助表示赞赏 我试图解决这个问题的原因是因为我有一个 RSS 源并且有一个标题和 URL 列表 我想将标题链接到 URL 以使
  • Chart.js 在初始化时设置活动段

    我正在使用 Chart js v2 并且尝试在加载图表时模拟圆环图上某个段的 悬停状态 因此看起来有一个部分已突出显示 我已经搜索和梳理了代码一天 但找不到一个好的方法来做到这一点 提前致谢 设置片段的悬停样式有点令人困惑 因为它没有真正记
  • 渲染货币和符号并与来自不同单元格的数据相结合

    我正在使用最新的 jQuery DataTables v1 10 7 我正在尝试将数字解析为以下格式 239 90 USD 我可以使用此命令使货币正常工作 columns data Price render fn dataTable ren
  • 为什么 iife 在一个简单的例子中不起作用?

    我不明白为什么函数表达式调用不起作用并抛出错误 你能给我解释一下吗 var a function x alert x function a 1 谢谢大家 任务比我想象的要容易得多 这是因为 JS 将 IIFE 解析为函数的参数调用 这样做时
  • 引导程序提前输入未填充承诺的响应

    我的引导程序预输入如下
  • Bootstrap按钮加载+Ajax

    我正在使用 Twitter Bootstrap 的按钮加载状态 http twitter github com bootstrap javascript html buttons http twitter github com bootst
  • 如何纠正流警告:解构(缺少注释)

    我正在编写一个小型 React Native 应用程序 并且正在尝试使用 Flow 但我无法在任何地方真正获得有关它的正确教程 我不断收到错误 destructuring Missing annotation 有关 station 这段代码
  • Angular - CSS - 自定义类型=文件输入,如何使用按钮而不是标签?

    我制作了一个类型为 file 的自定义输入字段 因为我不喜欢默认的输入字段 为了实现这一目标 我做了
  • 尝试将数据存储在点击器网站中

    我正在尝试存储一个名为的变量score无论何时刷新 您都会一次又一次地使用它 我不明白的是它的代码是什么 我尝试了一些方法 但似乎都不起作用 这是我的答题器网站 但是当我尝试使用 JavaScript 来存储它时 它不起作用window o
  • Chrome 扩展程序在代码中使用 client_secret

    我正在开发具有自己的 oAuth 授权的 Google Chrome 扩展 当然 我必须使用 client id 和 client secret 作为请求令牌 有什么办法可以向用户隐藏这些数据吗 由于此请求只是 javascript 源代码
  • 检查 jQuery 1.7 中是否存在基于文本的选择选项

    所以我有以下 HTML 片段
  • 有没有办法在 onclick 触发时禁用 iPad/iPhone 上的闪烁/闪烁?

    所以我有一个有 onclick 事件的区域 在常规浏览器上单击时 它不会显示任何视觉变化 但在 iPad iPhone 上单击时 它会闪烁 闪烁 有什么办法可以阻止它在 iPad iPhone 上执行此操作吗 这是一个与我正在做的类似的示例
  • Vuejs 2:去抖动不适用于手表选项

    当我在 VueJs 中反跳此函数时 如果我提供毫秒数作为原语 它就可以正常工作 但是 如果我将其提供为对 prop 的引用 它会忽略它 这是道具的缩写版本 props debounce type Number default 500 这是不
  • Firebase 函数 onWrite 未被调用

    我正在尝试使用 Firebase 函数实现一个触发器 该触发器会复制数据库中的一些数据 我想观看所有添加的内容votes user vote 结构为 我尝试的代码是 const functions require firebase func
  • 在移动设备上滚动

    这个问题更多的是一个建议研究 我确实希望它对其他人有帮助 并且它不会关闭 因为我不太确定在哪里寻求有关此事的建议 在过去的 6 个月里 我一直在进行移动开发 我有机会处理各种设备上的各种情况和错误 最麻烦的是滚动问题 当涉及到在网站的多个区
  • Three.js 各种大小的粒子

    我是 Three js 的新手 正在尝试找出添加 1000 个粒子的最佳方法 每个粒子都有不同的大小和颜色 每个粒子的纹理是通过绘制画布创建的 通过使用粒子系统 所有粒子都具有相同的颜色和大小 为每个粒子创建一个粒子系统是非常低效的 有没有
  • 使用 Vue 的多模式组件

    我在 Vue 中实现动态模式组件时遇到问题 A common approach I follow to display a set of data fetched from the db is I dump each of the rows
  • Vue 和 Vuex:处理依赖的计算属性

    我的应用程序是一个使用 Vuex 在 Vue 中构建的精简电子表格 关键组件是TableCollection Table and Row The TableCollection有一个包含多个的数组Table对象 每个Table有一个包含多个
  • 如何在生产模式下为 Chrome 扩展启用 Vue 开发工具?

    我正在构建一个 chrome 扩展 并使用 vue cli webpack 配置 我希望能够在运行后使用 vue devtoolsnpm 运行构建命令 我尝试添加Vue config devtools true 在 main js 中 或者
  • 带参数的事件监听器

    我想将参数传递给 JavaScript 中的事件侦听器 我已经找到了解决方案 但我无法理解它们为什么或如何工作以及为什么其他解决方案不起作用 我有 C C 背景 但是 Javascript 函数的执行有很大不同 您能否帮助我理解以下示例如何

随机推荐