Chrome扩展初接触

我目前在看英语网页的时候, 经常开着沉浸式翻译这个插件, 使用体验是很棒, 但是感觉这样容易形成依赖和偷懒的心理, 对提升英语阅读能力帮助不大。

我想自己做一个浏览器插件来自用,实现以下功能:

  1. 检测到网页为英文语言时自动启用。
  2. 将页面上的文本识别出来,拆分为独立的单词。
  3. 和本地存储的一个词库对比,不认识的单词标记为红色,不在词库中标记为绿色,已经认识的不做处理。
  4. 有颜色标记的单词可以点击并弹出模态窗口,在里面可以添加中文释义,查询词典,修改单词在词典中的状态。
  5. 将上面所述的改动替换回文本的原有节点,不影响整体页面布局的前提下,增强英语的阅读体验和交互性。

其实还是我在Lang Big Bang项目中所做的那些,只是在那里面是导入自己感兴趣的文章来学习英语。而插件可以在浏览任何一个网页时实现这个效果,更加自由并且灵活一些。目前我还想要开发一个 APP,长期的目标是数据互通,手机上可以学习,浏览器里随时可以阅读,网页上可以方便做导入。

大概看了下谷歌的开发文档, 做了一个小测验,目前感觉有实现的可能。做了一个小 demo,搭了一个大概的脚手架。

manifest.json 定义整个项目的结构、功能、权限,可以视为一个入口文件。

{
  "manifest_version": 3,
  "name": "Lang Bigbang",
  "version": "1.0",
  "description": "Learning english by reading in a simple way.",
  "icons": {
    "16": "images/icon-16.png",
    "32": "images/icon-32.png",
    "48": "images/icon-48.png",
    "128": "images/icon-128.png"
  },
  "content_scripts": [
    {
      "js": ["scripts/content.js"],
      "css": ["styles/content.css"],
      "matches": ["https://developer.chrome.com/*"]
    }
  ],
  "permissions": ["storage", "unlimitedStorage"]
}

content.js 测试了对页面文本的提取和注入 (dom 操作的 API,可以查看mdn 文档)。

之所以延时执行是因为要等页面本身的 js 先加载完成,以免读取不到文本或者读取不完整。

const tags = ['P', 'STRONG', 'EM', 'TIME', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6'];

function getText(node) {
  let text = '';
  if (node.nodeType === Node.TEXT_NODE) {
    if (tags.includes(node.parentNode.tagName)) {
      text += node.textContent + ' ';
    }
  } else if (node.nodeType === Node.ELEMENT_NODE) {
    for (let child of node.childNodes) {
      text += getText(child);
    }
  }

  return text;
}

setTimeout(function () {
  const body = document.querySelector('body');
  const allText = getText(body);

  if (allText) {
    const out = document.createElement('p');
    out.classList.add('bigtitle');
    out.textContent = allText;

    document.body.insertAdjacentElement('afterbegin', out);
  } else {
    console.log('No allText found');
  }
}, 2000);

接下来还有很多的细节需要完善, 比如本地存储怎么实现查词和写入? 更进一步的话,怎么实现本地数据和 supabase 互通同步,怎么做登录验证? 怎么替换原有的文本节点? 可能需要找某一天有大块的时间来研究下。 今天时间有限,先暂时做一个记录,以待后续。

What I Leraned?

  1. 实现一个扩展程序的流程。怎么创建文件和浏览器调试。manifest.json 的配置,图标、js\css、权限清单等。
  2. 通过 content_scripts 可以读取并修改目标网页的 dom。js 中操作页面 dom 的一些 api。