chrome 插件编写笔记

谷歌扩展的 abc

用来练手的小项目 - 改变浏览器背景颜色

创建 manifest.json

{
    "name": "my first demo",
    "description": "这是我的第一个 demo",
    "version": "1.0",
    "manifest_version": 3
}

manifest_version 是什么?

使用浏览器加载该扩展

  1. 更多工具 - 扩展程序或者直接访问chrome://extensions/
  2. 加载已解压的扩展程序 - 选择刚才的文件夹。

写错了 manifest.json 文件会报错找不到配置。

增加功能 - 后台程序(background script)

  1. manifest.json 中注册
{
    ....
    "background": {
        "service_worker": "background.js"
    }
}

background.js 在每次插件加载时运行。

  1. 编写 background.js
let color = '#1784d8'

chrome.runtime.onInstalled.addListener(() => {
  chrome.storage.sync.set({ color });
  console.log('已在 localstorage 中存储 color 信息')
  console.log('Default background color set to %cblue', `color: ${color}`);
});

此时重载会报错, 控制台 Failed to construct 'URL': Invalid URL

  1. 因为用到了 localstorage,需要添加权限
{
    ...
     "permissions": ["storage"]
}

重载正常,点击 servcie worker 可以看到输出内容。

增加功能 - 用户界面(user interface)

  1. 用户界面有很多种,demo 使用的是 popup。
  2. 创建 html 与 css。 ``` // index.html <!DOCTYPE html> demo
这是一个demo

</html>



button { height: 30px; width: 100px; / outline: none; / margin: 10px; / border: none; / border-radius: 2px; font-size: 10px; cursor: pointer; }

button.current { box-shadow: 0 0 0 2px white, 0 0 0 4px black; }

> chrome 教程中的代码未设置 `<meta charset="utf8">`,输中文会乱码。

3. 注册 `index.html`

{ //.... "action": { "default_popup": "index.html" } }


#### 给插件添加 icon

1. 下载教程提供的 icon 并解压。
2. 在 `manifest.json` 中配置。

{ //... "action": { //... "default_icon": { "16": "/images/get_started16.png", "32": "/images/get_started32.png", "48": "/images/get_started48.png", "128": "/images/get_started128.png" } } }


或者

{ //... "icons": { "16": "/images/get_started16.png", "32": "/images/get_started32.png", "48": "/images/get_started48.png", "128": "/images/get_started128.png" } }


> 第一种写法只能配置了装载后的 icon,在 `chrome://extensions/` 里是没有的;第二种可以兼顾。

#### 增加功能 - 添加 js 文件

1. 初始化 js 文件

// index.js // Initialize button with user's preferred color let changeColor = document.getElementById("changeColor");

chrome.storage.sync.get("color", ({ color }) => { changeColor.style.backgroundColor = color; });

```
//html
<!DOCTYPE html>
<html lang="zh">

<head>
    <meta charset="utf8">
    <link rel="stylesheet" href="index.css">
    <title>demo</title>
</head>

<body>
    <div>这是一个demo</div>
    <button id="changeColor">我是按钮</button>
</body>

</html>

<script src="index.js"></script>

script 标签似乎遵守严格的先后顺序,因此如果把 js 放在 button 之前会报空指针问题。

  1. js 增加逻辑

  2. manifest.json 中申请权限。

{
    // ...
    "permissions": ["storage", "activeTab", "scripting"],

}

未申请权限直接调用 js,因为使用到了 chrome.tabs.querychrome.scripting.executeScript 会报 null 错误。

  • 增加点击事件
// index.js
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,
  });
});

// The body of this function will be executed as a content script inside the
// current page
function setPageBackgroundColor() {
  chrome.storage.sync.get("color", ({ color }) => {
    const currentColor = document.body.style.backgroundColor
    chrome.storage.sync.set({ color:currentColor });
    document.body.style.backgroundColor = color;
  });
}

changeColor 似乎不需要进行初始化,chrome 会直接按照 id 初始化为变量。 chrome://extensions 不支持 script 注入(can not inject content scripts),请用真实网页。

增加选择菜单

  1. 新增一个 option.html 和对应的 option.js
<!DOCTYPE html>
<html>
  <head>
    <link rel="stylesheet" href="index.css">
  </head>
  <body>
    <div id="buttonDiv">
    </div>
    <div>
      <p>Choose a different background color!</p>
    </div>
    <script src="options.js"></script>
  </body>
</html>
let page = document.getElementById("buttonDiv");
let selectedClassName = "current";
const presetButtonColors = ["#3aa757", "#e8453c", "#f9bb2d", "#4688f1"];

// Reacts to a button click by marking the selected button and saving
// the selection
function handleButtonClick(event) {
  // Remove styling from the previously selected color
  let current = event.target.parentElement.querySelector(
    `.${selectedClassName}`
  );
  if (current && current !== event.target) {
    current.classList.remove(selectedClassName);
  }

  // Mark the button as selected
  let color = event.target.dataset.color;
  event.target.classList.add(selectedClassName);
  chrome.storage.sync.set({ color });
}

// Add a button to the page for each supplied color
function constructOptions(buttonColors) {
  chrome.storage.sync.get("color", (data) => {
    let currentColor = data.color;
    // For each color we were provided…
    for (let buttonColor of buttonColors) {
      // …create a button with that color…
      let button = document.createElement("button");
      button.dataset.color = buttonColor;
      button.style.backgroundColor = buttonColor;

      // …mark the currently selected color…
      if (buttonColor === currentColor) {
        button.classList.add(selectedClassName);
      }

      // …and register a listener for when that button is clicked
      button.addEventListener("click", handleButtonClick);
      page.appendChild(button);
    }
  });
}

// Initialize the page by constructing the color options
constructOptions(presetButtonColors);
  1. 注册 option
{
  ...
  "options_page": "options.html"
}
  1. 右键点击插件 - 选项,就可以进到刚才的 options 选项。

参考

results matching ""

    No results matching ""