什么是 Chrome 插件
谷歌浏览器在推出时就以其快速、安全和简洁的特点受到了广大用户的欢迎。随着浏览器的不断发展,谷歌为用户提供了插件开发平台,使开发者能够为浏览器添加各种功能和定制化选项。从此,插件成为了提升用户体验和个性化的重要工具。
谷歌浏览器插件是一种小型程序,可以增强浏览器的功能。谷歌浏览器插件使用HTML、CSS和JavaScript等网页开发技术,开发者可以使用这些技术来创建自己的谷歌浏览器插件。
谷歌浏览器插件的常见作用:
- 广告拦截:广告拦截插件可以帮助用户屏蔽网页上的广告,提高用户的浏览体验。
- 下载管理:下载管理插件可以帮助用户更好地管理他们的下载任务,包括暂停、恢复、取消等操作。
- 阅读模式:阅读模式插件可以将网页转换为更易于阅读的格式,去除不必要的元素和广告等。
- 密码管理:密码管理插件可以帮助用户管理他们的密码,并自动填写表单。
- 翻译:翻译插件可以帮助用户在浏览网页时翻译其他语言的内容,提高用户的阅读体验。
- 社交媒体:社交媒体插件可以帮助用户快速访问他们的社交媒体账户,分享内容和与朋友互动。
- 开发者工具:开发者工具插件可以帮助开发者调试和测试他们的网站和应用程序。
根据功能和使用方式的不同,可以将 Chrome 插件分为多种类型,例如:
- 浏览器操作类插件:如广告拦截器、密码管理器等,主要用于增强用户对浏览器的控制能力;
- 网页修改类插件:如用户样式表、网页字体修改器等,主要用于改变网页的外观和布局;
- 其他类型:如翻译软件、天气预报插件等。
它们能够个性化定制浏览器、增强功能、提升效率,并且通过开发者社区促进插件开发的创新和进步。
谷歌插件不仅提升了用户的浏览体验,还为开发者提供了一个创造和分享自己工具的平台。通过使用和探索谷歌插件,我们可以充分发挥浏览器的潜力,提高工作效率和生活品质。
Chrome 插件的运行原理
Chrome 插件采用了一种基于事件的编程模型,其运行原理如下:
-
插件加载:当用户在浏览器中安装并启用插件时,插件将被加载到浏览器中。此时,浏览器会读取插件目录中的 manifest.json 文件,根据其中的配置信息来加载插件。
-
插件初始化:一旦插件被加载到浏览器中,就会初始化插件。在这个过程中,插件会创建必要的对象和变量,并准备好处理来自浏览器和其他网站的请求和事件。
-
插件事件处理:当用户与浏览器交互时,例如单击插件图标或在网页中执行某些操作时,插件会收到事件。在这种情况下,插件会根据事件类型执行相应的操作。
-
插件响应:当插件接收到事件时,它会执行相应的操作。例如,如果用户单击插件图标,则插件可能会显示一个弹出窗口或打开一个新的标签页。
-
插件卸载:当用户不再需要插件时,可以从浏览器中卸载它。在这种情况下,浏览器会删除插件文件并清除相关的设置和数据。
当用户安装了一个 Chrome 插件后,该插件的代码将会被下载到用户的本地计算机上,并在以后的浏览器会话中执行。用户可以通过 Chrome 浏览器的扩展管理器对已安装的插件进行启用或禁用。
Chrome 插件开发基本结构
谷歌插件的内部机制是通过一系列的文件和目录来实现的,一个 Chrome 插件通常由以下组成部分组成:
- 清单文件(
manifest.json
):manifest.json
是插件的配置文件,这是插件的核心,它定义了插件的元数据和行为,包含插件名称、版本号、作者信息、插件的权限和其他元数据等。在这个文件中,可以指定插件的图标、背景页、内容脚本和其他资源。 - 背景页面(
background.js
):background.js
是插件的后台脚本,可以在后台运行,处理插件的事件和请求。例如,您可以使用background.js
来处理插件的启动和关闭事件,或者处理来自其他网站的请求。 - 内容脚本(
content_script
):content_scripts
是插件的内容脚本,可以注入到网页中与网页进行交互。它可以访问当前页面的 DOM 结构和 JavaScript 对象,以实现对页面的修改和操作。例如,您可以使用content_scripts
来修改网页元素、监听网页事件或者向网页注入自定义样式或脚本等。 - 弹出页面(
popup.html
):popup.html
是插件的弹出窗口页面,可以在用户点击插件图标时显示。可以在popup.html
中添加任何HTML、CSS和JavaScript代码,以显示有用的信息或提供交互式功能。 - 插件图标(
icon.png
):icon.png
是插件的图标文件,用于在谷歌浏览器中显示插件图标。
除了上述文件之外,还可以包含其他资源文件,例如CSS样式表、JavaScript脚本、图片和字体等。
OK,那我们话不多说,接下来我用两个插件来带你完全入门 Google 插件开发!
实战:Chrome 滤镜插件
首先,我们需要创建一个新的 Chrome 插件项目叫滤镜插件:
mkdir google_extensions_filter # 创建滤镜插件项目
cd google_extensions_filter # 进入项目根目录
touch manifest.json # 在你的项目根目录中创建一个名为 manifest.json 的文件
接下来我们来编写 manifest.json
:
{"manifest_version": 2, // manifest.json 文件版本号"name": "网页滤镜🔍", // 插件名称,字符串类型"version": "1.0", // 插件版本号,字符串类型"description": "更改当前网页滤镜🔍", // 插件描述,字符串类型"permissions": [ // 权限,该字段定义了插件需要访问的资源和功能,例如浏览器标签、存储、网络等等"activeTab" // 允许插件访问当前激活的标签页],"browser_action": { // 浏览器动作,该字段用于定义当用户单击浏览器操作按钮时执行的操作"default_title": "网页滤镜🔍", // 鼠标指针悬停在浏览器操作按钮上显示的默认标题"default_popup": "popup/popup.html", // 弹出窗口的 HTML 文件路径"default_icon": { // 默认图标的文件路径"128": "icon/icon128.png" // 128x128 像素的图标文件路径}},// 此属性对应用程序可以加载的资源设置限制"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'"
}
在清单配置文件里我们定义了插件的名称、版本、描述和所需的权限,还指定了插件的图标和默认弹出窗口
接下来我们在根目录创建 popup 文件夹,然后在里面创建一个名为 popup.html 的文件,并添加以下代码:
<!DOCTYPE html>
<html><head><meta charset="utf-8"><title>添加网页滤镜🔍</title><link rel="stylesheet" href="popup.css"></head><body><h1>添加网页滤镜🔍</h1><div class="box"><button id="changeFilterBtn"><span class="text">添加滤镜</span></button><button id="changeBlackFilterBtn"><span class="text">黑白滤镜</span></button><button id="resetFilterBtn"><span class="text">去除滤镜</span></button></div><script src="popup.js"></script></body></html>
我们写了一个简单的弹出窗口页面:包含一个标题(添加网页滤镜🔍)和三个按钮(添加滤镜、黑白滤镜、去除滤镜),然后我们来加一点css让这个页面变得炫酷起来:
body {min-width: 300px;min-height: 100px;}h1 {font-size: 28px;font-weight: bold;text-align: center;text-shadow: 2px 2px #f0f0f0;}.box {width: 100%;display: flex;justify-content: space-around;align-items: center;}button {align-items: center;background-image: linear-gradient(144deg,#AF40FF, #5B42F3 50%,#00DDEB);border: 0;border-radius: 8px;box-shadow: rgba(151, 65, 252, 0.2) 0 15px 30px -5px;box-sizing: border-box;color: #FFFFFF;display: flex;font-family: Phantomsans, sans-serif;font-size: 18px;justify-content: center;line-height: 1em;max-width: 100%;min-width: 140px;margin: 5px;padding: 3px;text-decoration: none;user-select: none;-webkit-user-select: none;touch-action: manipulation;white-space: nowrap;cursor: pointer;transition: all .3s;}button:active,button:hover {outline: 0;}button span {background-color: rgb(5, 6, 45);padding: 16px 24px;border-radius: 6px;width: 100%;height: 100%;transition: 300ms;}button:hover span {background: none;}button:active {transform: scale(0.9);}
好我们来看看现在的效果:
看起来还是蛮不错的,接下来为了使弹出窗口有更多的交互功能,我们需要为按钮添加 JavaScript
在popup文件夹中创建一个名为 popup.js 的文件,并添加以下代码:
// 添加滤镜
document.getElementById('changeFilterBtn').addEventListener('click', function () {chrome.tabs.executeScript({code: 'document.documentElement.style.filter = "hue-rotate(180deg)"'});
});// 添加黑白滤镜
document.getElementById('changeBlackFilterBtn').addEventListener('click', function () {chrome.tabs.executeScript({code: 'document.documentElement.style.filter = "grayscale(100%)"'});
});//去除滤镜
document.getElementById('resetFilterBtn').addEventListener('click', function () {chrome.tabs.executeScript({code: `document.documentElement.style.filter = "none"`});
});
代码非常简单,就是为每个按钮添加了事件监听器,分别监听添加滤镜、黑白滤镜、去除滤镜按钮的单击事件
在更改滤镜按钮的回调函数中,我们使用了 chrome.tabs.executeScript
方法,这个方法的作用是向当前选项卡中注入写入的 JavaScript 代码
现在我们的滤镜插件就完成了,接下来我们来使用一下看看有没有生效
打开谷歌浏览器,在地址栏中输入 chrome://extensions/
并回车。在扩展程序页面的右上角,点击 “开发者模式” 按钮,然后点击左上角的 “加载已解压的扩展程序” 按钮,选择刚刚我们的google_extensions_filter文件夹
让我们来看看滤镜插件最后的效果:(完美!)
实战:Chrome 记事本插件
你是不是觉得上面的例子太简单了?
那我们接着来写一个逻辑稍微复杂一点的记事本插件
我们和之前一样,先来创建一个新的 Chrome 插件项目叫 notebook:
mkdir google_extensions_notebook # 创建记事本插件项目
cd google_extensions_notebook # 进入项目根目录
touch manifest.json # 在项目根目录中创建一个名为 manifest.json 的文件
接下来我们也来编写 manifest.json
文件,参数配置基本上和刚刚的项目差不多:
{"manifest_version": 2,"name": "瑞萌萌的记事本🗒️","version": "1.0","description": "一个随便写写的记事本插件","browser_action": {"default_icon": {"16": "icon/icon16.png","128": "icon/icon128.png"},"default_title": "瑞萌萌的记事本🗒️","default_popup": "popup.html"},"permissions": ["storage"],"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'"}
然后我们在根目录创建一个名为 popup.html 的文件,并添加以下HTML代码:
<!DOCTYPE html>
<html><head><title>瑞萌萌的记事本🗒️</title><meta charset="utf-8" name="viewport" content="width=device-width, initial-scale=1.0"><link rel="stylesheet" href="popup.css"><script src="popup.js"></script></head><body><h1>瑞萌萌的记事本🗒️</h1><div id="note-list"></div><textarea id="note-textarea" rows="5" placeholder="请输入您的笔记"></textarea><!-- <div id="note-content" contenteditable="true"></div> --><button id="add-button">添加笔记</button><button id="clear-button">清空笔记</button></body>
</html>
来点 CSS 装饰一下:
body {font-family: Arial, sans-serif;font-size: 16px;line-height: 1.5;margin: 0;padding: 0;min-width: 600px;background: linear-gradient(to bottom right, #ffafbd, #ffc3a0);
}h1 {font-size: 28px;font-weight: bold;text-align: center;text-shadow: 2px 2px #f0f0f0;
}#note-list {margin: 0 10px;padding: 0 20px;
}.note-item {border: 1px solid #ccc;border-radius: 15px;margin-bottom: 20px;padding: 10px 150px 10px 10px;position: relative;background-color: white;
}.note-text {margin-bottom: 10px;
}.copy-button {box-shadow:inset 0px 1px 0px 0px #efdcfb;background:linear-gradient(to bottom, #dfbdfa 5%, #bc80ea 100%);background-color:#dfbdfa;border-radius:27px;border:3px solid #c584f3;color: #fff;cursor: pointer;font-size: 14px;margin-left: 10px;padding: 5px 15px;position: absolute;right: 80px;top: 50%;text-decoration:none;text-shadow:0px 1px 0px #9752cc;transform: translateY(-50%);transition: background-color 0.3s ease-in-out;}.copy-button:hover {background:linear-gradient(to bottom, #bc80ea 5%, #dfbdfa 100%);background-color:#bc80ea;}
.delete-button {box-shadow:inset 0px 1px 0px 0px #8a2a21;background:linear-gradient(to bottom, #c62d1f 5%, #f24437 100%);border-radius:27px;border:3px solid #ffffff;color: #fff;cursor: pointer;font-size: 14px;margin-left: 10px;padding: 8px 17px;position: absolute;text-decoration: none;text-shadow: 0px 1px 0px #b23e35;right: 10px;top: 50%;transform: translateY(-50%);transition: background-color 0.3s ease-in-out;
}.delete-button:hover {background:linear-gradient(to bottom, #f24437 5%, #c62d1f 100%);background-color:#f24437;
}#note-textarea {border: 1px solid #ccc;border-radius: 15px;font-family: Arial, sans-serif;font-size: 16px;line-height: 1.5;margin: 0 35px;padding: 10px;resize: none;width: calc(85%);
}#add-button, #clear-button {background-color: #4caf50;border: none;border-radius: 20px;box-shadow: 0 1px 3px rgba(0,0,0,0.3);color: #fff;cursor: pointer;font-size: 14px;padding: 10px 30px;margin: 10px 10px 20px 120px;transition: background-color 0.3s ease-in-out, box-shadow 0.3s ease-in-out;
}#add-button:hover, #clear-button:hover {background-color: #388e3c;
}
效果还不错,大家也可以根据自己的审美来设计
现在我们就可以开始写我们记事本的逻辑啦,我希望这个记事本插件能做到:
- 文本框输入笔记内容后添加笔记进入笔记列表
- 点击复制按钮可以复制添加的任意一条笔记内容
- 点击删除按钮可以删除笔记列表中的任意一条笔记
- 点击清空笔记可以删除所有记录的笔记
- 复制内容到文本框添加笔记,点击复制按钮时保留复制文本的格式
- 笔记列表存储在Chrome浏览器中,所有标签页共用
🆗 需求明确,还等什么,JS直接冲:
// 渲染笔记列表
function renderNoteList(notes) {var noteList = document.getElementById("note-list");noteList.innerHTML = "";for (var i = 0; i < notes.length; i++) {// 创建笔记项var noteItem = document.createElement("div");noteItem.className = "note-item";// 创建笔记文本var noteText = document.createElement("div");noteText.className = "note-text";noteText.textContent = notes[i];// 创建复制按钮var copyButton = document.createElement("button");copyButton.className = "copy-button";copyButton.textContent = "复制";// 创建删除按钮var deleteButton = document.createElement("button");deleteButton.className = "delete-button";deleteButton.textContent = "删除";// 绑定删除按钮的点击事件deleteButton.addEventListener("click", (function(index) {return function() {// 删除对应的笔记notes.splice(index, 1);// 更新笔记列表chrome.storage.sync.set({notes: notes}, function() {renderNoteList(notes);});};})(i));// 获取所有复制按钮var copyButtons = document.querySelectorAll('.copy-button');// 给每个复制按钮添加点击事件copyButtons.forEach(copyButton => {copyButton.addEventListener('click', () => {// 获取要复制的文本内容const noteContent = copyButton.previousElementSibling ? copyButton.previousElementSibling.textContent.trim() : copyButton.previousSibling.textContent.trim();// 创建一个临时textarea元素const tempTextarea = document.createElement('textarea');tempTextarea.value = noteContent;// 将临时textarea元素添加到body中,并选中其中的文本document.body.appendChild(tempTextarea);tempTextarea.select();// 复制文本内容到剪贴板document.execCommand('copy');// 移除临时textarea元素document.body.removeChild(tempTextarea);});});// 添加笔记文本和删除按钮到笔记项noteItem.appendChild(noteText);noteItem.appendChild(copyButton);noteItem.appendChild(deleteButton);// 添加笔记项到笔记列表noteList.appendChild(noteItem);}
}// 当DOM加载完成时执行以下代码
document.addEventListener("DOMContentLoaded", function() {var noteList = [];var noteTextarea = document.getElementById("note-textarea");var addButton = document.getElementById("add-button");var clearButton = document.getElementById("clear-button");// 绑定添加按钮的点击事件addButton.addEventListener("click", function() {var note = noteTextarea.value;if (note) {// 将笔记添加到笔记列表noteList.push(note);// 更新笔记列表chrome.storage.sync.set({notes: noteList}, function() {renderNoteList(noteList);});// 清空笔记输入框noteTextarea.value = "";}});// 保留复制文本的格式信息noteTextarea.addEventListener("paste", function(e) {e.preventDefault();var text = e.clipboardData.getData("text/plain");document.execCommand("insertHTML", false, text);});// 绑定清空按钮的点击事件clearButton.addEventListener("click", function() {// 清空笔记列表noteList = [];// 更新笔记列表chrome.storage.sync.remove("notes", function() {renderNoteList(noteList);});});// 获取存储在Chrome浏览器中的笔记列表chrome.storage.sync.get("notes", function(data) {if (data.notes) {// 如果存在笔记列表,则将其赋值给noteList变量noteList = data.notes;// 渲染笔记列表renderNoteList(noteList);}});// 设置插件图标chrome.browserAction.setIcon({ path: 'icon/icon128.png' });// 设置插件标题chrome.browserAction.setTitle({ title: '瑞萌萌的记事本🗒️' });
});
代码每一部分我都写了注释,具体实现过程可以自己看一下上面的代码
现在我们的记事本插件就完成啦,我们来在浏览器里加载一下插件,看看实地效果怎么样
完美!所有需求功能都已实现!
怎么样,经过上面两个 Chrome 插件实战,你有没有觉得 Chrome 插件开发其实没有你想的那么难!
写在最后:
Chrome 插件是一种非常有用的工具,它可以帮助开发者扩展浏览器的功能,提高用户体验
在本文中,我们详细讲解了谷歌浏览器插件的基础知识、运行原理、开发实战等方面
通过本文的学习,你应该已经掌握了如何创建一个谷歌浏览器插件,并且了解如何在浏览器里使用它
希望本文能够帮助你更好地理解 Chrome 插件开发,并激发对 Chrome 插件开发的兴趣,进一步探索和创造更多有趣、实用的插件。加油!
本文所有的代码都放到了https://github.com/KongC-X/chrome_extensions,欢迎自取!