乐于分享
好东西不私藏

Chrome插件开发入门:自定义新标签页

Chrome插件开发入门:自定义新标签页

Chrome 扩展开发完全指南:从零打造个性新标签页

本文不仅会系统讲解 Chrome 扩展的核心概念,还会通过一个完整的实战项目——自定义新标签页,带你一步步掌握扩展开发的完整流程。无论你是前端新手还是想拓展技术栈的开发者,都能从中受益。


一、Chrome 扩展基础

Chrome 扩展本质上是 HTML、CSS、JavaScript 文件的集合,可以增强浏览器功能、修改网页行为、提供自定义界面等。它由几个关键组件构成,下面我们逐一介绍。

1. 核心文件:manifest.json

每个扩展都必须有一个 manifest.json 文件,它就像应用的“身份证”,声明了扩展的名称、版本、权限以及各功能模块的入口。

最小示例

json

{
"manifest_version": 2,
"name""我的第一个扩展",
"version""1.0",
"description""一个简单的Chrome扩展",
"browser_action": {
"default_popup""popup.html"
  },
"permissions": ["activeTab"]
}
  • manifest_version:当前必须为 2(或 3,但本文基于 V2)。
  • browser_action:定义工具栏图标及点击后弹出的页面(default_popup)。
  • permissions:声明需要访问的 Chrome API 或网站权限。

2. 扩展的主要组件

  • 背景脚本(Background Script) :运行在后台,处理事件、管理状态。在 V2 中可以是持久页面或事件页面。
  • 内容脚本(Content Script) :注入到网页中,可以读取/修改 DOM,但受同源策略限制。
  • 弹出页面(Popup) :点击工具栏图标时显示的小窗口,通常用于快速交互。
  • 选项页面(Options Page) :用户自定义扩展设置的页面。
  • 覆盖页面(Override Pages) :可以覆盖浏览器的默认页面,如新标签页、历史记录页等。

3. 调试与安装

  • 打开 chrome://extensions,开启“开发者模式”。
  • 点击“加载已解压的扩展程序”,选择你的项目文件夹即可安装。
  • 扩展的代码修改后,点击刷新按钮即可重新加载。

二、实战项目:chrome-theme —— 自定义新标签页

本项目是一个功能完整的新标签页替换扩展,支持:

  • 动态显示时间(年月日、星期、时分秒)
  • 每日一句“彩虹屁”
  • 可切换的搜索引擎(百度、必应、谷歌)
  • 本地/网络图片作为背景,并自动提取主色调整文字颜色
  • 最近访问历史记录
  • 实时天气信息(基于IP定位)

📸 效果预览

安装扩展后,新标签页将呈现如下样式(实际运行截图):

项目结构

.
├── README.md
├── asset/font                # 自定义字体文件
├── background.html           # 新标签页的HTML结构
├── css/background.css        # 样式文件
├── img/                      # 扩展图标
├── inject/index.js           # 注入所有页面的脚本(本项目中为空)
├── js/
│   ├── background.js         # 主逻辑:页面初始化、事件绑定
│   ├── chrome_runtime.js     # Chrome特定功能(历史记录)
│   ├── comm_js.js            # 公共辅助函数
│   ├── localstorage.js       # 本地存储初始化
│   ├── search_engine.js      # 搜索引擎配置
│   └── weather.js            # 天气功能
└── manifest.json

1. manifest.json 详解

{
"name""wangfpp-theme",
"version""0.1.0",
"description""自定义Chrome主题",
"manifest_version"2,
"browser_action": {
"default_icon""img/64.png"
  },
"background": {
"scripts": [ "js/background.js" ],
"css": [ "css/background.css" ]
  },
"chrome_url_overrides": {
"newtab""background.html"
  },
"content_scripts": [ 
    {
"all_frames"true,
"js": [ "inject/index.js" ],
"match_about_blank"true,
"matches": [ "<all_urls>" ],
"run_at""document_start"
    } 
  ],
"content_security_policy""script-src 'self' 'unsafe-eval'; object-src 'self'",
"permissions": [ "fontSettings""<all_urls>""tabs""storage""unlimitedStorage""topSites""contextMenus""history""fileBrowserHandler" ]
}

重点解读

  • chrome_url_overrides:指定覆盖的页面,"newtab": "background.html" 表示每次新建标签页都会加载 background.html
  • background:声明后台脚本和样式。这里 scripts 和 css 会构成一个后台页面,后台脚本可以一直运行(V2 特性)。
  • content_scripts:向所有页面注入脚本(本项目中为空),可用于实现全局样式修改。
  • permissions:请求了多项权限,包括 history(读取历史记录)、storage(本地存储)、<all_urls>(访问所有网站)等,这些都是实现功能所必需的。

2. 新标签页页面 background.html

这个文件定义了新标签页的布局。为了简洁,我们只展示关键部分:

<divclass="date"></div>
<inputid="search"type="text"placeholder="搜索一下...">
<divid="chp"></div>
<divclass="weather"></div>
<divid="history_container"></div>
<divid="set_btn">⚙️</div>
<divid="menu"class="hidemenu">
<!-- 搜索引擎切换、背景设置等 -->
</div>

样式写在 css/background.css 中,你可以自由调整布局、字体和配色。

3. 核心功能实现

3.1 时间实时更新(background.js

window.onload = e => {
let date_node = document.querySelector('.date');
if (date_node) {
    date_node.innerHTML = formatDateString();
    setInterval(() => {
if (date_node) {
        date_node.innerHTML = formatDateString();
      }
    }, 1000);
  }
}

formatDateString 定义在 comm_js.js 中,返回包含时、分、秒和年月日的 HTML 字符串。

3.2 搜索引擎切换

配置文件 search_engine.js 定义了搜索引擎字典:

const search_gine_dict = {
"baidu": {
text"百度",
create_urlval =>`https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&rsv_idx=1&tn=baidu&wd=${val}`
  },
"biying": {
text"必应",
create_urlval =>`https://www.bing.com/search?q=${val}`
  },
"google": {
text"谷歌",
create_urlval =>`http://www.google.cn/search?q=${val}&hl=zh-CN&client=aff- 360daohang&hs=yhE&affdom=360.cn&newwindow=1&start=10&amp; amp;sa=N`
  }
}

在 background.js 中,监听搜索框回车事件:

input_node.onkeydown = function (e{
let { keyCode, target } = e;
let { value } = target;
if (keyCode === 13 && value) {
let engine = window.localStorage.getItem("search_engine") || search_gine_list[0];
let url = search_gine_dict[engine].create_url(value);
window.location.href = url;
    target.value = "";
  }
}

菜单中的单选框用于修改本地存储的搜索引擎值。

3.3 背景图片与动态取色(亮点功能)

用户可以上传本地图片或输入网络图片 URL 作为背景,扩展会分析图片中特定区域(日期区域、天气区域、彩虹屁区域)的主色,并设置文字颜色为反色,以保证对比度。

关键代码在 background.js 的 setRootBG 函数中:

functionsetRootBG(url{
if (root_node) {
    root_node.setAttribute("style"`background: url(${url});background-size: cover`);
let image = new Image();
    image.onload = function(e{
if (storage.getItem("color_width_img") == "1") {
// 获取各区域的位置和大小
let { offsetTop, offsetLeft, offsetWidth, offsetHeight } = chp_node;
let { width, height } = e.target;
if (!(width >= 2000 || height >= 2000)) { // 避免大图性能问题
let pixel = getImagePix(image); // 获取像素矩阵
let _date_color = areaPixAverage(pixel, [0166], [053]);      // 日期区域
let weather_color = areaPixAverage(pixel, [width-188, width], [060]); // 天气区域
let chp_color = areaPixAverage(pixel, [offsetLeft, offsetLeft + offsetWidth], [offsetTop, offsetTop + offsetHeight]); // 彩虹屁区域
          setSearchBg(input_node, pixel);
// 通过CSS变量传递颜色
          root_node.style.setProperty("--date_color", _date_color);
          root_node.style.setProperty("--weather-color", weather_color);
          root_node.style.setProperty("--chp_color", chp_color);
        }
      }
    }
    image.src = url;
  }
}
  • getImagePix:将图片绘制到 canvas,提取每个像素的 RGBA 值,生成二维数组。
  • areaPixAverage:计算指定矩形区域的平均 RGB,并返回其反色。
  • 搜索框的背景色也会根据区域亮度动态调整(深色背景配浅色文字,反之亦然)。

3.4 彩虹屁 API

functioncreateChp(node{
  fetch('https://chp.shadiao.app/api.php?').then(res => res.text())
    .then(res => {
if (res && node) node.innerHTML = res;
    });
}

这个 API 返回纯文本,直接插入即可。

3.5 天气功能(weather.js

流程:

  1. 通过 ip-api.com 获取当前 IP 的经纬度(免费,无需密钥)。
  2. 将经纬度 POST 给 data.cma.cn(中国气象局数据接口)获取实时天气。
  3. 更新 DOM,展示城市、天气状况、温度、风力等。
  4. 每 3 小时自动刷新。
fetch(`http://ip-api.com/json/?lang=zh-CN`).then(res => res.json())
  .then(res => {
let { lat, lon } = res;
    fetch("http://data.cma.cn/kbweb/home/live", {
method"POST",
bodyJSON.stringify({ lat, lon, type"1" }),
headers: { "Content-type""application/json" }
    }).then(res => res.json())
      .then(res => {
// 解析并渲染天气数据
      });
  });

注意:由于 API 可能变更,实际使用时建议替换为更稳定的天气服务(如和风天气、OpenWeatherMap),并处理好跨域问题(可在后台脚本中请求)。

3.6 历史记录显示(chrome_runtime.js

利用 Chrome 的 chrome.history.search API 获取最近 10 条记录:

if (window.localStorage.getItem("show_history") == "1") {
  chrome.history.search({text''maxResults10}, function(data{
let history_item = "";
    data.forEach(function(page{
      history_item += `
        <div class="history_item">
          <a href="${page.url}">
            <img src="chrome://favicon/size/20@2x/${page.url}" alt="icon"/>
            <p class="title">${page.title}</p>
          </a>
        </div>
      `
;
    });
    history_container.innerHTML = history_item;
  });
else {
  history_container.style.display = "none";
}

注意:需要在 manifest 中申请 "history" 权限。

4. 本地存储初始化(localstorage.js

在扩展首次运行时,设置默认值:

localStorage.getItem("search_engine") || localStorage.setItem("search_engine""baidu");
localStorage.getItem("screen_bg") || localStorage.setItem("screen_bg""https://images.pexels.com/photos/417074/pexels-photo-417074.jpeg");
localStorage.getItem("color_width_img") || localStorage.setItem("color_width_img""0");
localStorage.getItem("show_history") || localStorage.setItem("show_history""0");

5. 辅助函数(comm_js.js

提供了常用的 DOM 操作和格式化函数,如 addClassremoveClassdoubleNumweekParse 等,方便复用。


三、打包与发布

  1. 在 chrome://extensions 中,点击“打包扩展程序”。
  2. 选择项目根目录,Chrome 会自动生成 .crx 和 .pem 文件(私钥请妥善保管)。
  3. 如果你想发布到 Chrome 网上应用店,需要注册开发者账号(一次性费用),上传包含所有文件的 zip 包,等待审核。

四、扩展与优化建议

  • 性能优化:背景取色时对过大图片做了限制,你也可以考虑使用 createImageBitmap 或 Web Worker 处理像素数据。
  • 天气 API 替换:现有 API 可能不稳定,建议改用免费且稳定的接口,如和风天气(需注册)、OpenWeatherMap(需 API Key)。
  • 添加更多小部件:你可以在 background.html 中自由添加模块,比如名言警句、待办事项等。
  • 适配 Manifest V3:Chrome 即将全面转向 V3,迁移时需要将后台脚本改为 Service Worker,并调整权限声明。可参考官方迁移指南。

五、结语

通过这个项目,我们不仅掌握了 Chrome 扩展的基本开发流程,还深入实践了图片处理、API 调用、Chrome 特有 API 的使用。希望你能在此基础上发挥创意,打造出属于自己的个性化浏览器工具。

如果你在开发过程中遇到问题,欢迎在评论区交流,也欢迎给项目点个 star 支持一下~

项目完整代码:[GitHub 仓库地址](https://github.com/wangfpp/chrome_theme)