WebBlur Chrome插件开发总结

项目简介

这是我第一次开发Chrome扩展,选择做一个网页模糊效果插件chrome-web-blur。想法很简单:有时候在公共场合看网页,不想让别人看到内容,或者某些网页太花哨影响注意力,希望能快速给页面加个模糊效果。

项目用了Chrome扩展的Manifest V3,主要功能包括:

  • 用快捷键Ctrl+B快速开关模糊效果
  • 可以调节模糊程度(1-20px)
  • 设置会自动保存
  • 所有标签页都能同步状态

为什么做这个项目

想法来源

平时在图书馆或者咖啡厅用电脑,总担心别人看到我在看什么。有时候网页广告太多,也很影响注意力。就想能不能做个简单的插件,按个快捷键就能让页面变模糊。

学习目标

  1. 学习Chrome扩展开发
  2. 熟悉Manifest V3的新特性
  3. 尝试做一些实用的东西

技术选型

用到的技术

  • Manifest V3: Chrome扩展的新标准,听说V2要淘汰了
  • JavaScript: 主要是ES6的async/await语法
  • CSS: 用backdrop-filter实现模糊效果
  • Chrome API: 存储、消息传递、快捷键等

项目结构

1
2
3
4
5
6
7
8
9
WebBlur/
├── manifest.json # 扩展配置
├── popup.html # 弹出窗口
├── popup.css # 弹出窗口样式
├── popup.js # 弹出窗口逻辑
├── content.js # 页面内容脚本
├── background.js # 后台脚本
├── styles.css # 全局样式
└── images/ # 图标文件

主要功能实现

1. 模糊效果

核心就是用CSS的backdrop-filter属性。我创建了一个全屏的div,然后给它加模糊效果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 创建模糊遮罩层
function createBlurOverlay() {
blurOverlay = document.createElement('div');
blurOverlay.style.cssText = `
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
backdrop-filter: blur(${blurIntensity}px);
-webkit-backdrop-filter: blur(${blurIntensity}px);
pointer-events: none;
z-index: 2147483647;
transition: backdrop-filter 0.3s ease;
`;
}

关键点:

  • pointer-events: none 让鼠标事件穿透,不影响页面交互
  • z-index: 2147483647 确保在最顶层
  • 加了transition让模糊效果有动画

2. 快捷键

在manifest.json里配置快捷键,用Chrome的Commands API:

1
2
3
4
5
6
7
8
9
10
{
"commands": {
"toggle-blur": {
"suggested_key": {
"default": "Ctrl+B"
},
"description": "切换模糊效果"
}
}
}

这样用户按Ctrl+B就能快速开关模糊效果,不用每次都点插件图标。

3. 设置保存

用Chrome的storage.sync API保存用户设置:

1
2
3
4
5
6
7
8
9
10
// 保存设置
async function saveSettings(newSettings) {
await chrome.storage.sync.set(newSettings);
}

// 加载设置
async function loadSettings() {
const result = await chrome.storage.sync.get(defaultSettings);
return result;
}

这样设置会自动同步到用户的所有Chrome浏览器,还挺方便的。

4. 模块间通信

Chrome扩展的不同部分需要互相通信,我用消息传递的方式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 发送消息
await chrome.tabs.sendMessage(tabId, {
action: 'toggleBlur',
enabled: enabled
});

// 接收消息
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
switch (message.action) {
case 'toggleBlur':
// 处理模糊切换
break;
case 'updateIntensity':
// 处理强度更新
break;
}
});

这部分刚开始有点绕,后来慢慢理解了。

界面设计

设计想法

界面尽量简单,用户一眼就能看懂怎么用。主要就是一个开关和一个滑块,再加点状态提示。

主要组件

  1. 开关: 用CSS做了个好看的开关按钮
  2. 滑块: 调节模糊程度,范围1-20px
  3. 状态显示: 显示当前是否开启,还有快捷键提示

样式

1
2
3
4
5
6
7
8
9
10
11
12
13
/* 开关样式 */
.toggle-slider {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
border-radius: 20px;
transition: all 0.3s ease;
}

/* 滑块样式 */
.slider {
background: linear-gradient(to right, #667eea, #764ba2);
border-radius: 5px;
height: 6px;
}

颜色选了紫色渐变,看起来比较现代。

遇到的问题

问题1: 页面兼容性

有些网站会动态修改DOM,导致我加的模糊遮罩层被删掉了。解决方法是监听DOM变化:

1
2
3
4
5
6
7
// 监听DOM变化
const observer = new MutationObserver(() => {
if (blurEnabled && blurOverlay && !document.body.contains(blurOverlay)) {
document.body.appendChild(blurOverlay);
applyBlurEffect();
}
});

问题2: 消息发送失败

有时候content script还没加载完,消息就发送失败了。加了重试机制:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
async function sendMessageWithRetry(tabId, message, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
const response = await chrome.tabs.sendMessage(tabId, message);
return response;
} catch (error) {
if (i < maxRetries - 1) {
await new Promise(resolve => setTimeout(resolve, 500 * (i + 1)));
} else {
throw error;
}
}
}
}

问题3: 标签页状态不同步

切换标签页时,模糊效果状态可能不一致。用Chrome Storage解决了:

1
2
3
4
5
6
// 页面加载时检查并应用模糊效果
chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
if (changeInfo.status === 'complete') {
checkAndApplyBlurEffect(tabId);
}
});

功能总结

主要功能

  1. 快捷键: Ctrl+B快速开关模糊效果
  2. 强度调节: 1-20px可调节模糊程度
  3. 设置保存: 自动记住用户偏好
  4. 跨页面同步: 所有标签页都能同步状态

其他功能

  1. 智能检测: 自动识别不支持的页面(如chrome://页面)
  2. 错误处理: 加了try-catch,避免插件崩溃
  3. 性能优化: 用CSS滤镜,性能还不错
  4. 动画效果: 模糊效果有平滑过渡

后续想法

  1. 自定义快捷键: 让用户自己设置快捷键
  2. 区域模糊: 只模糊页面的某个区域
  3. 定时功能: 定时开启/关闭模糊效果
  4. 主题切换: 支持深色主题

总结

这个项目是我第一次开发Chrome扩展,虽然功能比较简单,但是学到了很多东西。