TagDown 扩展程序开发——体验优化
TagDown 是一款开源的书签管理插件, 您可以使用扩展程序浏览、新增、修改书签,它也支持以不同方式导出书签。
除了常见的书签管理功能,还具有以下特点:
支持 ???? 新增书签,并附加额外的信息,例如
tags
、groups
等支持 ???? 导出任意书签为
json
文档以 ???? 树图的形式浏览层级结构的书签数据
一键打开多个书签,支持在 ???? 标签组内打开书签
图标动态更改
扩展程序的后台是一个 service worker,基于监控事件-作出响应的模式执行命令。
可以在后台监控标签页的切换事件,查询当前激活标签页 URL 是否与任何已保存的书签相匹配,动态更改 Action 图标。实现类似于 Chrome 地址栏右侧的星型图标切换状态,以指示当前标签是否已收藏的功能。
⚠️ 如果希望在后台脚本中 import
引入其他库,需要在配置清单 manifest.json
中将后台脚本类型声明为模块
{ // ... "background": { "service_worker": "./background/main.js", "type": "module" }, // ... } 复制代码
主要使用 Chrome 提供的两个 APIs 实现该功能:
chrome.action.setIcon
动态设置 Action 图标chrome.tabs.onActivated
监听标签激活事件
// src/backrground/main.js // ... /** * 基于当前激活标签是否被收藏,动态更改 Action 图标 */ const changeActionIcon = async (tag = false) => { if (tag) { await chrome.action.setIcon({ path: { 16: '/icons/icon16_tag.png', }, }); } else { await chrome.action.setIcon({ path: { 16: '/icons/icon16_untag.png', }, }); } }; // 监听标签激活事件,回调函数接收一个对象入参,它包含激活标签的 tabId chrome.tabs.onActivated.addListener(async (activeInfo) => { // 基于激活标签的 tabId 获取标签对象,从而得到相应的 url const tab = await chrome.tabs.get(activeInfo.tabId); const url = tab.url || tab.pendingUrl; // 基于 url 查找是否有已收藏的书签与之匹配,返回一个包含所有匹配书签节点的数组 const nodes = await chrome.bookmarks.search({ url, }); let bookmarkState = false; if (nodes.length === 0) { // 未找到匹配书签 bookmarkState = false; } else { // 找到至少一个匹配书签 bookmarkState = true; } // 基于书签匹配情况更改 Action 图标 await changeActionIcon(bookmarkState); }); 复制代码
???? 还可以基于监控其他事件,动态更改 Action 图标:
chrome.windows.onFocusChanged
浏览器窗口更改事件chrome.tabs.onUpdated
标签更新事件,例如标签页的 URL 更改时chrome.bookmarks.onCreated
新增书签事件
数据导出
在设置页面中主要提供了 IndexedDB 数据库的导出、导入,以及书签按需导出功能。
目前有多种库支持在前端将数据导出为文件,例如 FileSaver.js、download.js,在 TagDown 的配置页中,用 Vanilla JS 实现了类似的功能:
// src/options/App.vue const exportJsonFile = (blob, fileName) => { if (!blob) return; const a = document.createElement('a'); const url = window.URL.createObjectURL(blob); a.href = url; a.download = `${fileName}.json`; a.click(); }; // 将对象型数据转换为 JSON 格式 const jsonData = JSON.stringify(data, null, 2); // 再基于 JSON 格式的数据创建 Blob 数据 const blob = new Blob([jsonFile], { type: 'application/json' }); // 再触发下载操作 exportJsonFile(blob, '数据导出') 复制代码
移除滚动条
由于 Chrome 限制弹出页面的大小,高和宽的最小值都是是 25px,高的最大值是 600px,宽的最大值是 800px。因此为了尽可能利用空间显示内容,TagDown 将弹出页的浏览状态设置为最大限制
<style scoped> // src/popup/App.vue .browser-mode { width: 800px; height: 600px; } // ... </style> 复制代码
但是此时弹出页就会出现滚动条,可以在弹出页的入口文件 ???? src/popup.html
中为 <body>
元素添加样式,取消它的滚动条
<!DOCTYPE html> <html lang="en"> <head> <!-- 省略部分代码 --> <style> body::-webkit-scrollbar { width: 0px; height: 0px; } </style> </head> <!-- 省略部分代码 --> </html>
作者:Benbinbin
链接:https://juejin.cn/post/7018843893928034335