chrome插件开发学习

446 阅读5分钟

「这是我参与2022首次更文挑战的第9天,活动详情查看:2022首次更文挑战

1, chrome插件

如今,一个浏览器也不知道安装了多个插件,掘金插件,极客插件,CSDN插件,等等,插件的市场越来越大了,而且插件的功能也越来越齐全,插件给我们的工作,学习都带来了便利,最近也最学习chrome浏览器插件开发, 记录一下整个开发的过程。

粘贴一下自己常用的几个插件:

1643200478316.png

2, Chrome Extensions

打开浏览器: 地址栏输入: chrome://extensions/ 就可以管理本地所有的Chrome插件。 插件程序使用HTML, JS, CSS来构建,运行与独立,沙箱式的环境,并且可以调用浏览器相关API。借助插件我们可以管理浏览器书签,设置主题,开发调试,网络抓包,等等

插件发展至今, 最新的开发规范已经更新到: Manifest V3, 目前市场上大多还使用Manifest V2, 需要注意的是:2023年1月份之后,Chrome将不再支持Manifest V2扩展程序的更新和运行,所以,我们如果学习就直接学习V3

3, 插件结构

一个完整的插件有五个模块组成

Manifest, Background Page, Popup, Content Script, Options Page

详细解释:

(1) Manifest

​ 用来配置插件的配置项,是插件开发必不可少的,必须放在更目录下面,它有三个必填字段

manifest_version, name, version
manifest_version: #使用的manifest版本,目前最新版本3
icons: # 插件的图标资源
background: {
   service_worker: #项目的入口文件,在此处注册事件
}
action: {
  default_popup:# 弹窗页
}
options_page: #配置管理页
permissions: # 脚本允许使用的API资源列表
content_scripts: # 扩展程序向页面注入的脚本资源
web_accessible_resources: #普通页面能够直接访问的插件资源列表
default_locale: #默认语言

(2)Background Page

是一个在后头持续运行的常驻页面,随着扩展加载而运行,知道浏览器关闭而停止,它负责维护扩展程序的全局状态,还可以和其他扩展通信,background的权限非常高,可以调用所有Chrome扩展API

(3)Popup

点击插件时的弹窗,提供了基本的交互功能,有些插件没有弹窗

(4)Content Scripts

内容脚本作用域web页面上下文,通过DOM操作来获取页面信息,操作页面节点,并能够将信息传递回扩展程序,可以注入到页面内,但是与页面的JS隔离,可以提前配置脚本的执行时机,默认:run_at: document_idle , 表示页面空闲时期

(5)Option

插件的后台管理页面,右键扩展程序图标,点击菜单里面的选项,即可打开选项页面

4,实战换肤插件

1, 创建文件夹chrome, 子该文件的根目录下:创建: manifest.json, 配置如下:

{
  "name": "换肤",
  "description": "换肤插件",
  "version": "1.0",
  "manifest_version": 3
}

然后直接进入chrome://extensions/ 点击加载已解压的扩展程序选择chrome文件夹,导入到浏览器中,一个没有任何功能的插件加载完毕。

效果如图:

1643203387073.png

(2) 创建:background.js

根目录下添加background.js, 通过chrome.storage API 存储一个颜色值,并打印,并且在manifest.json中声明权限,然后重新加载插件

background.js配置如下:

let color = "#3aa757";
chrome.runtime.onInstalled.addListener(() => {
  chrome.storage.sync.set({color})
  console.log('默认背景色设置为:%cgreen', `color: ${color}`)
})

manifest.json配置如下;

{
  "name": "换肤",
  "description": "换肤插件",
  "version": "1.0",
  "manifest_version": 3,
  "background": {
    "service_worker": "background.js"
  },
  "permissions": ["storage"]
}

(3) 创建用户界面

根目录下创建:popup.html,并添加到manifest.json中,在popup.html中引入css.js文件, 目的:实现了点击图标,就会展示弹窗,焦点离开网页就会立即关闭弹窗。其中:

action.default_icon: 是工具栏的图标,

icons:是扩展管理页面icon

注意:要授权: chrome.scripting, chrome.tabs, activeTab

代码如下;

popup.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>popup</title>
  <link rel="stylesheet" href="button.css">
</head>
<body>
  <button id="changeColor"></button>
  <script src="popup.js"></script>
</body>
</html>

manifest.json

{
  "name": "换肤",
  "description": "换肤插件",
  "version": "1.0",
  "manifest_version": 3,
  "background": {
    "service_worker": "background.js"
  },
  "permissions": ["storage", "scripting", "tabs", "activeTab"],
  "action": {
    "default_popup": "popup.html",
    "default_icon": {
      "16":"/images/boy-5.png",
      "32":"/images/boy-5.png",
      "48":"/images/boy-5.png",
      "128":"/images/boy-5.png"
    },
    "icons": {
      "16":"/images/boy-5.png",
      "32":"/images/boy-5.png",
      "48":"/images/boy-5.png",
      "128":"/images/boy-5.png"
    }
  }
 }

button.css

button {
  height: 30px;
  width: 30px;
  outline: none;
  margin: 10px;
  border: none;
  border-radius: 2px;
}
button.current {
  box-shadow: 0 0 0 2px white, 0 0 0 4px black;
}

popup.js

let changeColor = document.getElementById('changeColor');
    chrome.storage.sync.get("color", ({color}) => {
      changeColor.style.backgroundColor = color
    });
    changeColor.addEventListener('click', async () => {
      let [tab] = await chrome.tabs.query({active: true, currentWindow: true});
          chrome.scripting.executeScript({
            target: { tabId : tab.id },
            function: setPageBackgroundColor,
          })
    });
function setPageBackgroundColor() {
  chrome.storage.sync.get('color', ({color}) => {
    document.body.style.backgroundColor = color
  })
}
  

(4) 完善选项功能

通过右键扩展程序图标,然后点击选项可以打开

根目录下新建:options.html, options.js

options.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>options</title>
  <link rel="stylesheet" href="button.css">
</head>
<body>
  <div id="buttonDiv"></div>
  <div>
    <p>Choose a different background color !</p>
  </div>
</body>
<script src="options.js"></script>
</html>

options.js

let changeColor = document.getElementById('changeColor');
    chrome.storage.sync.get("color", ({color}) => {
      changeColor.style.backgroundColor = color
    });
    changeColor.addEventListener('click', async () => {
      let [tab] = await chrome.tabs.query({active: true, currentWindow: true});
          chrome.scripting.executeScript({
            target: { tabId : tab.id },
            function: setPageBackgroundColor,
          })
    });
function setPageBackgroundColor() {
  chrome.storage.sync.get('color', ({color}) => {
    document.body.style.backgroundColor = color
  })
}
  

(5) 消息通信让脚本自动运行

使用content_scripts向页面注入脚本,并和background.js建立消息机制。content_scripts.js向background.js发送消息传递请求,background.js接收到请求后,从storage中异步读取到颜色值后,再向tab页面发送信息传递数据,content_scripts.js获取到数据后再修改DOM完成流程。

manifest.json

{
 "content_scripts": [
    {
      "matches": [
        "https://www.baidu.com/*"
      ],
      "run_at": "document_idle",
      "js": [
        "content-script.js"
      ]
    }
  ]
}

background.js

// 接收消息处理
chrome.runtime.onMessage.addListener((req, sender, sendRes) => {
   const tabId = sender.tab.id;
   sendRes('颜色获取中');
   chrome.storage.sync.get('color', ({color}) => {
     // 发送获取信息
     chrome.tabs.sendMessage(tabId, color, function(res) {
       console.log('信息发送成功')
     })
   })
})

content-script.js

// 发送信息请求
chrome.runtime.sendMessage({data: 'getStorageColor'}, res => {
  console.log(res);
})
// 接收消息处理
chrome.runtime.onMessage.addListener((req, sender, sendRes) => {
  document.body.style.backgroundColor = req;
  sendRes(true)
})

当你打开百度页面,可以背景颜色会自动更换

完整的manifest.json文件:如下:

{
  "name": "换肤",
  "description": "换肤插件",
  "version": "1.0",
  "manifest_version": 3,
  "background": {
    "service_worker": "background.js"
  },
  "permissions": ["storage", "scripting", "tabs", "activeTab"],
  "action": {
    "default_popup": "popup.html",
    "default_icon": {
      "16":"/images/boy-5.png",
      "32":"/images/boy-5.png",
      "48":"/images/boy-5.png",
      "128":"/images/boy-5.png"
    },
    "icons": {
      "16":"/images/boy-5.png",
      "32":"/images/boy-5.png",
      "48":"/images/boy-5.png",
      "128":"/images/boy-5.png"
    }
  },
  "options_page": "options.html",
  "content_scripts": [
    {
      "matches": [
        "https://www.baidu.com/*"
      ],
      "run_at": "document_idle",
      "js": [
        "content-script.js"
      ]
    }
  ]
}

效果如图:

1643204862956.png

详细的API文档可参考:developer.chrome.com/docs/extens…

5, 项目源码

项目代码地址和文档中的截图都是同步的,都已经实现, 在chrome文件夹中

[持续更新中]

gitee.com/jamiedawn/t…