chrome插件实时通信的几种方式

chrome插件开发中我们知道,background.js是独立于浏览器的,在background.js中主要负责popupcontent.js的交互,在某些时候,也许你需要在一个插件的设置页与content进行实时通信,此时你能想到什么样的方式吗?本文是在插件业务通信总结的一篇笔记,希望看完能在实际业务中带来思考和帮助

正文开始...

在插件通信中,我们先从backgroundpopupcontent中来一起重温那些常用的通信交互

background.js

chrome.runtime.onMessage.addListener监听content.js发送过来的消息

js 复制代码
// background.js
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
  const { type } = request;
  console.log(request)
  if (type === "open_set_page") {
    // 打开设置页
    chrome.runtime.openOptionsPage();
  }
})

content.js

content.js中,使用chrome.runtime.sendMessage(params),当我们在content.js点击设置按钮时,此时就会打开设置页,此时会触发backrgound.js

js 复制代码
// content.js
const setBtnDom = document.getElementById("set");
setBtnDom.onclick = function () {
    // 向background.js传入消息
    chrome.runtime.sendMessage({
      type: "open_set_page",
    });
};

设置页与background.js通信

我们在content.js中打开了一个设置页,此时如果设置页向与content进行通信,那么该怎么办呢?

我们尝试在设置页background.js中发送消息

js 复制代码
 document.getElementById("light").onclick = function () {
    console.log("light");
    // changeTheme,向background发送消息
    chrome.runtime.sendMessage({ type: "changeTheme", theme: "light" });
  };

我们会发现backrgound.js中接收到了来自set页面的信息

js 复制代码
// background.js
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
  const { type } = request;
  // 打开设置页面
  if (type == "open_set_page") {
    chrome.runtime.openOptionsPage();
  }
  if (type === "changeTheme") {
    console.log(request, "=request");
  }
});

在一个插件的内部页面与content实时通信

比如现在有个场景,我在设置页需要设置content页面的主题,而且需要实时修改,那么怎么办呢?

主要利用chrome.tabs.querychrome.tabs.sendMessage这两个api实现

js 复制代码
  // set.js
  function sendMessageToActiveTab(message) {
    // 获取当前活动标签
    chrome.tabs.query({}, function (tabs) {
      tabs
        .filter((v) => v.active)
        .forEach((v) => {
          chrome.tabs.sendMessage(v.id, message);
        });
    });
  }
  let flag = true;
  document.getElementById("dark").onclick = function () {
    flag = !flag;
    sendMessageToActiveTab({ action: "buttonClicked", theme: flag ? "dark" : "light" });
  };

content.js中我们监听set.js发送过来的消息

js 复制代码
const textDom = document.getElementById("text");
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
  console.log(sender.id, chrome.runtime.id);
   const {theme} = request;
   textDom.style.color = theme === 'dark' ? "black": "red"
});

此时你会发现当你在设置点击按钮操作时,当前激活的tab就会实时触发

但是有一个场景,就是我想修改所有的content的状态,那该怎么办呢?

其实我们只需要修改一行代码即可

js 复制代码
 function sendMessageToActiveTab(message) {
    // 向所有的tabde
    chrome.tabs.query({}, function (tabs) {
      tabs
        .forEach((v) => {
          chrome.tabs.sendMessage(v.id, message);
        });
    });
  }

缓存

当你在设置页修改状态时,content确实是可以实时变化了,但是,当你刷新,当前的状态的就会改变,所以你需要如何保持当前状态,那么你需要用到插件的缓存功能

在使用缓存功能之前,你需要在permission中添加storage

json 复制代码
{
   "permissions": ["storage"]
}

在插件的设置页面

js 复制代码
  // set.js
  let flag = true;
  document.getElementById("dark").onclick = function () {
    flag = !flag;
    // port.postMessage({ type: "changeTheme", theme: "dark" });
    const theme = flag ? "dark" : "light";
    sendMessageToActiveTab({
      action: "buttonClicked",
      theme,
    });
    chrome.storage.local.set({ theme });
  };

content.js

js 复制代码
// content.js
chrome.storage.local.get("theme", function (result) {
  console.log(result, "result");
  const { theme = "" } = result || { theme: "" };
  if (theme === "dark") {
    textDom.style.color = "black";
  } else {
    textDom.style.color = "red";
  }
});

当你在chrome设置页设置缓存时,你在content重新刷新,那么就可以正常的获取缓存了。

总结

  • 了解content.jsbackground.js的通信,或者是popupcontent的通信,借助chrome.runtime.sendMessage实现

  • 在插件的内部页面如何与其他页面通信,比如一个插件的设置页与content.js实时通信,我们是借助先查询所有的tabs,chrome.tabs.query({}, callback),然后再向所有的tabs发送消息chrome.tabs.sendMessage(id, data),最后在content.jschrome.runtime.onMessage监听发送过来的消息

  • code example

相关推荐
别拿曾经看以后~1 小时前
【el-form】记一例好用的el-input输入框回车调接口和el-button按钮防重点击
javascript·vue.js·elementui
我要洋人死1 小时前
导航栏及下拉菜单的实现
前端·css·css3
川石课堂软件测试1 小时前
性能测试|docker容器下搭建JMeter+Grafana+Influxdb监控可视化平台
运维·javascript·深度学习·jmeter·docker·容器·grafana
科技探秘人1 小时前
Chrome与火狐哪个浏览器的隐私追踪功能更好
前端·chrome
科技探秘人1 小时前
Chrome与傲游浏览器性能与功能的深度对比
前端·chrome
JerryXZR1 小时前
前端开发中ES6的技术细节二
前端·javascript·es6
七星静香1 小时前
laravel chunkById 分块查询 使用时的问题
java·前端·laravel
q2498596931 小时前
前端预览word、excel、ppt
前端·word·excel
小华同学ai2 小时前
wflow-web:开源啦 ,高仿钉钉、飞书、企业微信的审批流程设计器,轻松打造属于你的工作流设计器
前端·钉钉·飞书
problc2 小时前
Flutter中文字体设置指南:打造个性化的应用体验
android·javascript·flutter