仅20+行核心代码的Chrome插件,这不是有手就行吗?(下)

简介: 接上文。

开发调试


Chrome 插件没有严格的项目结构要求,只要保证根目录有一个 manifest.json 即可,也不需要专门的 IDE 进行开发。


开发调试时,进入插件管理页面最简洁的方式是在地址栏输入chrome://extensions/进行访问。其他两种进入插件管理页面的方式如下图所示:


d2093056525079c1f4862d8da14e2fc0.png


50d918693e6a1af3e2b6692a6cdeee59.png


打开右上角开发者模式便可以文件夹的形式直接加载插件,否则只能安装.crx 格式的文件。默认情况下,Chrome 要求插件必须从它的 Chrome 应用商店安装,其它任何网站下载的以及自己打包的都无法直接安装。所以,其实我们可以把 crx 文件解压,然后通过开发者模式直接加载。


de4518cbfac827f830a370b4342ef1bd.png


开发过程中,代码有任何改动都必须重新加载插件,点击对应插件的重新加载按钮或者刷新当前插件管理页面均可。如果出现错误,将会出现类似下面的界面,更改后,你需要先点击“错误”按钮进入弹窗对错误进行清除。


b4aef555c28c975b5fe219f1bb0642ae.png


开发过程中遇到的更多细节可以参考官方Debugging extensions[4]文档。


3 分钟写一个浏览器插件,解决某 SDN 未登录无法复制代码的问题


我们知道,前段时间某 SDN 更新后,未登录时,无法复制文章中的代码,给开发者带来一定不便。今天我们就花 3 分钟时间写一个浏览器插件,突破这种限制。


基本思路其实很简单,通过将当前页面的document.body.contentEditable值设置为true来达到可复制的效果。当然,这个我们通过控制台面板或者“自定义书签“的方式也能轻松实现,这里只是让大家体验一下简单插件的开发,避免出手就是”Hello World!“,😄


某 SDN 给代码块儿设置了user-select: none;,导致无法进行选中复制,从这里入手亦可。


书签功能的实现可参考前端装逼技巧 108 式(一)—— 打工人[5]


下面将逐步介绍项目各文件相关信息,您也可以直接点击这里[6]在线查看完整代码。整个项目核心代码不足 30 行,相信您能藉此迅速入门 Chrome 插件开发,激发兴趣和潜能,写出更有用的插件或者应用。


目录结构


  目录结构图:


3fe78d7ced08d8fee4b8ac09973ea1b7.png


  目录解释:


  • images


  • logo.png:插件图标。


  • js


  • popup.js:弹窗 popup.html 中使用的 js;


  • content_script.js:需要直接注入页面的 js;


  • manifest.json:配置文件,插件开发中的必备项;


  • popup.html:插件弹窗;


  • style.css:弹窗样式文件;


manifest.json 配置文件


{
  // 清单文件的版本,必须是2或者3,
  // 文档见 https://developer.chrome.com/docs/extensions/mv3/manifest/manifest_version/
  "manifest_version": 2,
  // 插件的名称
  "name": "Copy SDN",
  // 插件的版本
  "version": "1.0.0",
  // 插件描述
  "description": "不登录依然可以在某SDN页面进行代码复制!",
  // 指定扩展在Chrome 工具栏中的图标,它定义了扩展图标文件位置(default_icon)、
  // 悬浮提示(default_title)和点击扩展图标所显示的页面位置(default_popup)
  "browser_action": {
    "default_title": "Hello, 某SDN!",
    "default_icon": "/images/logo.png", // 浏览器右上角图标设置
    "default_popup": "popup.html"
  },
  // https://developer.chrome.com/docs/extensions/mv2/manifest/icons/
  // 128x128 的图标;它在安装期间和 Chrome 网上应用店使用
  // 48x48 图标,用于扩展程序管理页面 (chrome://extensions)
  // 16x16 图标用作扩展页面的收藏夹图标
  // 这里只写一个其实也是可以的
  "icons": {
    "128": "/images/logo.png"
  },
  // 需要直接注入页面的JS
  "content_scripts": [
    {
      //"matches": ["http://*/*", "https://*/*"],"<all_urls>" 表示匹配所有地址
      "matches": ["https://blog.csdn.net/*"],
      // 多个JS按顺序注入
      "js": ["/js/content_script.js"],
      // "css": ["css/custom.css"],
      // 代码注入的时间,可选值: "document_start", "document_end", or "document_idle",
      // document_idle表示页面空闲时,为默认值
      "run_at": "document_start"
    }
  ],
  // 定义了扩展需要向 Chrome 申请的权限,比如通过 XMLHttpRequest 跨域请求数据、访问浏览器选项卡(tabs)
  // 获取当前活动选项卡(activeTab)、浏览器通知(notifications)、存储(storage)等,可以根据需要添加。
  "permissions": ["tabs"]
}


popup.html 和 css 制作插件弹窗


popup.html


<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="stylesheet" href="./style.css" />
    <title>Copy SDN</title>
  </head>
  <body>
    允许复制Code:<input type="checkbox" class="switch" id="toggle" />
    <!-- 这里引入了popup.js,来给popup弹窗添加一些交互功能 -->
    <script src="./js/popup.js"></script>
  </body>
</html>


弹窗样式文件style.css


body {
  width: 160px;
  height: 24px;
  background-color: lavender;
  display: flex;
  justify-content: center;
  align-items: center;
}
/* Switch开关样式 */
input[type='checkbox'].switch {
  outline: none;
  appearance: none;
  -webkit-appearance: none;
  -moz-appearance: none;
  position: relative;
  width: 40px;
  height: 20px;
  background: #ccc;
  border-radius: 10px;
  transition: border-color 0.3s, background-color 0.3s;
}
input[type='checkbox'].switch::after {
  content: '';
  display: inline-block;
  width: 1rem;
  height: 1rem;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0, 0, 2px, #999;
  transition: 0.4s;
  top: 2px;
  position: absolute;
  left: 2px;
}
input[type='checkbox'].switch:checked {
  background: rgb(19, 206, 102);
}
/* 当input[type=checkbox]被选中时:伪元素显示下面样式 位置发生变化 */
input[type='checkbox'].switch:checked::after {
  content: '';
  position: absolute;
  left: 55%;
  top: 2px;
}

  

以上代码将构建出如下插件弹窗 UI:


dcd0df36cabb37d2df0b12f742c2dea6.png


popup.js 给弹窗添加交互


// 这里的js其实是操作popup.html产生的dom的
document.addEventListener('DOMContentLoaded', function () {
  // 获取开关按钮的初始值。这里{ type: 'get_editable' }是可以随意定义的,可以传递任何你想传递的信息
  sendMessageToContentScript({ type: 'get_editable' }, (response) => {
    toggle.checked = ['true', true].includes(response) ? 'checked' : null;
  });
  // 切换contentEditable状态
  toggle.addEventListener('change', () => {
    sendMessageToContentScript({ type: 'toggle' });
  });
});
// 向content_scripts发送消息的函数
function sendMessageToContentScript(message, callback) {
  // 这里用到了tabs,所以前面配置文件需要配置"permissions": ["tabs"]
  chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
    chrome.tabs.sendMessage(tabs[0].id, message, (response) => {
      if (callback) callback(response);
    });
  });
}


content_script.js 向页面注入 JS


// 所谓content-scripts,其实就是Chrome插件中向页面注入脚本的一种形式(虽然名为script,其实还可以包括css),
// 借助content-scripts我们可以实现通过配置的方式轻松向指定页面注入JS和CSS(如果需要动态注入,可以参考下文),
// 最常见的比如:广告屏蔽、页面CSS定制,等等。
// 接收消息
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
  // 数据处理和返回。是不是有点类似redux中reducer数据处理的感觉
  switch (request.type) {
    case 'get_editable':
      // 将当前文档是否可编辑的信息返回给popup,控制开关的形态
      sendResponse(document.body.contentEditable);
      break;
    case 'toggle':
      // 切换可编辑状态
      document.body.contentEditable = ![true, 'true'].includes(
        document.body.contentEditable
      );
    default:
      break;
  }
});


打包与发布


在插件管理页左上角有一个“打包扩展程序”的按钮,点击就会出现如下界面,选择要打包的文件夹进行打包即可,你会得到一个.crx的压缩文件,这个实际上就是你经常安装插件时安装的压缩包文件。


17a125ea413dba75fa2040d8dd4cf937.png


98c655778f2821acd906643da1060a89.png


要发布到 Google 应用商店的话,需要先支付 5 美元的注册费成为开发者:Register as a Chrome Web Store Developer[7]


7dee21cdead2ef90b7c70123829374ce.png

相关文章
|
2月前
|
Web App开发 JavaScript 前端开发
使用vue快速开发一个带弹窗的Chrome插件
使用vue快速开发一个带弹窗的Chrome插件
67 0
使用vue快速开发一个带弹窗的Chrome插件
|
2月前
|
Web App开发 JavaScript 前端开发
从零开始,轻松打造个人化Chrome浏览器插件
从零开始,轻松打造个人化Chrome浏览器插件
71 0
|
5月前
|
Web App开发 存储 前端开发
一键同步,无处不在的书签体验:探索多电脑Chrome书签同步插件
一键同步,无处不在的书签体验:探索多电脑Chrome书签同步插件
112 0
|
5月前
|
Web App开发 存储 缓存
(新)Chrome浏览器自定义背景插件
(新)Chrome浏览器自定义背景插件
107 0
|
3月前
|
Web App开发 前端开发
Chrome 浏览器插件 V3 版本 Manifest.json 文件中 Action 的类型(Types)、方法(Methods)和事件(Events)的属性和参数解析
Chrome 浏览器插件 V3 版本 Manifest.json 文件中 Action 的类型(Types)、方法(Methods)和事件(Events)的属性和参数解析
156 0
|
2月前
|
Web App开发 内存技术
chrome插件安装方法教程
chrome插件安装方法教程
|
4月前
|
Web App开发 安全 定位技术
Chrome浏览器书签同步插件floccus与坚果云的协同使用方法
Chrome浏览器书签同步插件floccus与坚果云的协同使用方法
|
4月前
|
Web App开发 存储 JavaScript
写一个Chrome浏览器插件(manifest v3)
写一个Chrome浏览器插件(manifest v3)
|
4月前
|
Web App开发
GOOGLE chrome浏览器 非插件截图方法
emm...不知道大家知不知道,反正不管怎么样,我就拿来水一下 打开chrome 哦~ 右键审查元素 or F12 or ctrl+shit+i or 你自己设置的快捷键... 然后再ctrl+shit+p
127 0
|
4月前
|
Web App开发 JavaScript 前端开发
从浏览器原理出发聊聊Chrome插件
本文从浏览器架构演进、插件运行机制、插件基本介绍和一些常见的插件实现思路几个方向聊聊Chrome插件。
766 0