首页 / 浏览器扩展开发入门教程 / action 与工具栏图标

浏览器扩展开发入门教程

action 与工具栏图标

本教程共 56 篇 · 第 7 篇 · 更新于 2026-08-13 · 约 6 分钟阅读

action工具栏弹出页图标default_popupdefault_title

本节目标:学完你能用 action 字段在浏览器工具栏上放出一个按钮,点击弹出自己写的页面,并配好图标和鼠标悬停提示。

扩展想让用户随时能点到,最自然的入口就是工具栏上的那个按钮。在 Manifest V3 里,这个按钮由 action 字段统一声明。它管三件事:按钮长什么样(图标)、鼠标悬停显示什么(标题)、点下去弹出什么(弹出页)。

这一节我们把 action 拆开讲:为什么 V3 只有一个 action、三个子字段怎么填、以及怎么在代码里动态改它们。

7-1 action 是唯一的工具栏入口

先说一个容易混淆的点。早期扩展平台里工具栏按钮分两种:一种常驻、一种只在特定页面出现。到了 V3,这两种合成了一个 action。也就是说,现在你想在工具栏放按钮,只有一个字段要写,就是 action

{
  "manifest_version": 3,
  "name": "我的标签整理器",
  "version": "1.0.0",
  "action": {
    "default_popup": "popup/popup.html",
    "default_icon": {
      "16": "icons/icon-16.png",
      "32": "icons/icon-32.png"
    },
    "default_title": "点击整理标签页"
  }
}

action 本身是个对象,下面挂 default_popupdefault_icondefault_title 三个子字段。这三个都可以单独省,但省了会有默认行为,后面逐个说。

Note

action 管的是工具栏按钮。扩展整体图标那是上一节讲的 icons,别把两者写混。一个是”扩展长什么样”,一个是”工具栏上那个能点的按钮长什么样”。

7-2 default_popup 点开就是一页

default_popup 指向一个 HTML 文件,用户点按钮时浏览器会弹出一个小窗口显示这个页面。它是字符串类型,写相对清单的路径。

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

弹出页本质就是一个普通的 HTML 页面,你可以写结构、引样式、引脚本,跟写网页一模一样。区别是它活在扩展自己的小窗口里,尺寸由内容决定,不能拖大拖小。

典型的 popup.html 长这样:

<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="utf-8" />
    <link rel="stylesheet" href="popup.css" />
  </head>
  <body>
    <button id="group">整理标签页</button>
    <script src="popup.js"></script>
  </body>
</html>

对应的 popup.js 用普通 DOM 写法就行:

document.getElementById("group").addEventListener("click", () => {
  chrome.tabs.query({ currentWindow: true }, (tabs) => {
    console.log("当前窗口有", tabs.length, "个标签");
  });
});
Tip

弹出页打开后,点页面外部任意处就会关闭。所以别在里面做需要”一直看着”的长任务,那种活该交给后台。弹出页适合放轻量交互:开关、快捷按钮、状态一览。

如果你不写 default_popup,点按钮就不会弹页面,而是触发一个 action 的点击事件,你可以在后台用 chrome.action.onClicked 监听它。两种模式二选一:要么弹页面,要么走点击事件。

7-3 default_icon 按钮自己的图标

default_icon 声明工具栏按钮上显示的图标。它有两种写法。简单写法是直接给一个字符串路径:

{
  "action": {
    "default_icon": "icons/icon-32.png"
  }
}

更常见的是给不同尺寸各一张,让浏览器按屏幕清晰度自己挑:

{
  "action": {
    "default_icon": {
      "16": "icons/icon-16.png",
      "32": "icons/icon-32.png"
    }
  }
}

图标用 PNG,建议备 16 和 32 两种。高分屏(比如 Retina)上 32 会更清晰。如果不写 default_icon,浏览器会用上一节 icons 里的图顶上,但专门给按钮配一张更贴合的图体验更好。

Note

工具栏按钮图标和扩展整体图标是两回事。整体图标在商店和扩展管理页用,按钮图标在工具栏用。分别声明,互不干扰。

7-4 default_title 鼠标悬停提示

default_title 是字符串,用户把鼠标停在按钮上时会显示这行字,相当于 tooltip。

{
  "action": {
    "default_title": "点击整理标签页"
  }
}

写一句最直白的操作提示最有用,比如”点击整理标签页""打开翻译面板”。用户不用点开就知道这按钮干嘛。不写的话,浏览器默认显示扩展的 name,也能用,但针对性差一点。

7-5 在代码里动态改 action

清单里写的是默认值,但很多场景你需要运行时改它。比如未登录时按钮置灰、有新消息时角标显示数字。这些靠 chrome.action 这组方法在后台或弹出页里调用。

改标题:

chrome.action.setTitle({ title: "已整理 3 组" });

改图标:

chrome.action.setIcon({ path: "icons/icon-active-32.png" });

改弹出页(比如登录后换成另一个页面):

chrome.action.setPopup({ popup: "popup/loggedin.html" });

在按钮上显示角标文字(那个小红点数字):

chrome.action.setBadgeText({ text: "3" });
chrome.action.setBadgeBackgroundColor({ color: "#d93025" });
Tip

角标(badge)是吸引注意的好手段,但别滥用。一直挂个大红数字,用户容易烦继而卸载。数字归零时记得把 text 设回空字符串 "",角标才会消失。

这些动态方法不写在清单里,而是在 JS 中按状态调用。清单只负责”出厂默认”,运行时的变化交给代码。

7-6 按钮可以按需显示和禁用

除了改图标、标题、角标,你还能控制按钮”在不在”和”能不能点”。这俩场景很实用:比如扩展只在特定网站生效,那就只在该网站显示按钮;或者功能还没就绪,先把按钮置灰。

在特定标签页显示按钮,用 showhide,需要传标签页 id:

// 只在 example.com 显示按钮
chrome.tabs.onUpdated.addListener((tabId, info, tab) => {
  if (tab.url && tab.url.includes("example.com")) {
    chrome.action.show(tabId);
  } else {
    chrome.action.hide(tabId);
  }
});

让按钮可点或置灰,用 enabledisable

chrome.action.disable(); // 全局置灰,用户点了没反应
chrome.action.enable();  // 恢复可点
Tip

默认情况下按钮是全局显示的。如果你只想在特定页面出现,记得在清单里配上 host_permissions 让扩展能读到标签页地址,否则上面的 tab.url 会是空的。权限那节我们会细讲,这里先知道有这个配合关系。

再补一个 7-2 提到的点:当你不写 default_popup 时,点按钮不会弹页面,而是走点击事件。监听方式如下:

chrome.action.onClicked.addListener((tab) => {
  console.log("按钮被点了,当前标签是", tab.id);
});

注意弹出页和点击事件互斥:写了 default_popuponClicked 就不会触发;想用 onClicked,就把 default_popup 去掉。两者选其一,别同时指望。

7-7 一个完整的 action 示例

把三个子字段和前面的基础字段合起来,一份能让工具栏出现按钮的清单就齐了:

{
  "manifest_version": 3,
  "name": "我的标签整理器",
  "version": "1.0.0",
  "description": "一键把杂乱的标签页按域名分组。",
  "icons": {
    "16": "icons/icon-16.png",
    "48": "icons/icon-48.png",
    "128": "icons/icon-128.png"
  },
  "action": {
    "default_popup": "popup/popup.html",
    "default_icon": {
      "16": "icons/btn-16.png",
      "32": "icons/btn-32.png"
    },
    "default_title": "点击整理标签页"
  }
}

目录结构大致是:

extension/
  manifest.json
  icons/
    icon-16.png
    icon-48.png
    icon-128.png
    btn-16.png
    btn-32.png
  popup/
    popup.html
    popup.css
    popup.js
Note

路径写错是最常见的加载失败原因。浏览器报”找不到文件”时,先核对清单里的路径和实际文件位置是否一字不差,尤其大小写。Linux 内核的浏览器对大小写敏感,Windows 上写错可能本地能跑、上架后却挂。

action 是用户和扩展之间最直接的桥梁。把弹出页、图标、标题配好,再配合运行时动态修改,你就拥有了一个既好看又好用的工具栏入口。下一节我们讲 background,给扩展安一个不在前台、却随时能干活的后台大脑。