Chrome Extensions (谷歌插件)开发入门 您所在的位置:网站首页 谷歌趋势插件是什么 Chrome Extensions (谷歌插件)开发入门

Chrome Extensions (谷歌插件)开发入门

2022-11-21 07:49| 来源: 网络整理| 查看: 265

Chrome extensions 概况 什么是 Chrome extensions

浏览器扩展程序 extensions 是一个小型的程序,它可以使用浏览器提供的 API 和 web 技术以增强浏览器功能。它们让用户可以通过多种方式定制 Chrome 的功能和行为,例如生产力工具、信息聚合、 丰富网页内容等

官方说明:

Extensions are made of different, but cohesive, components. Components can include background scripts, content scripts, an options page, UI elements and various logic files. Extension components are created with web development technologies: HTML, CSS, and JavaScript.. 扩展由不同但有凝聚力的组件组成。组件可以包括背景脚本、内容脚本、选项页面、UI 元素和各种逻辑文件。扩展组件是使用 Web 开发技术创建的:HTML、CSS 和 JavaScript。

Chrome插件官方称为Chrome扩展(Chrome Extension),真正意义上的Chrome插件是更底层的浏览器功能扩展。本文遵循官方文档,称为Chrome扩展。

Chrome extensions 能干什么

增强浏览器功能,轻松实现属于自己的“定制版”浏览器。

参考官方文档:Extension development overview Chrome插件提供了很多实用API供我们使用,包括但不限于:

书签控制; 自定义扩展用户界面 下载控制; 窗口控制; 标签控制; 网络请求控制,各类事件监听; 自定义原生菜单; 完善的通信机制;

请访问Chrome 应用商店查看已发布扩展程序示例。

截屏2022-09-28 15.09.13.png

安装 Chrome 拓展

大多数 Chrome 用户从 Chrome 应用商店获取扩展程序,也可以在本地机器上安装

本地机器上安装 在浏览器中导航到 chrome://extensions。还可以通过单击多功能框右上角的 Chrome 菜单、将鼠标悬停在更多工具上并选择扩展来访问此页面

截屏2022-09-28 16.05.45.png

选中开发者模式,单击加载已解压的扩展程序

截屏2022-09-28 16.06.24.png

Hello World

hello world 代码仓库 v1

安装示例:

截屏2022-09-28 16.41.50.png

架构概述

扩展程序依其功能的不同,项目的结构和所包含的文件类型也不同,但是它们一般都由以下部分构成:

Manifest:每一个扩展程序都必须有一个配置清单 manifest.json 文档,在其中清楚地包含该扩展程序的相关信息和所需使用的权限。

Service worker:Service worker是扩展的事件处理程序;它包含对浏览器事件的侦听器。 它处于休眠状态,直到触发事件然后执行指示的逻辑;它仅在需要时加载并在空闲时卸载。Service Worker 可以访问所有 Chrome API,只要它在 manifest.json 中声明了所需的权限

Content Script:内容脚本,它可以植入页面,一般用于读取页面内容,或向页面插入内容。

UI element ui 包括: Action badge 、 Popup 、 Tooltip 、Click Event 、 Omnibox 、 Context menu 、 Commands 、 Override pages 、 Notifications

Manifest V3

每一个扩展程序都需要有一个配置清单 manifest.json 文档,它提供了关于扩展程序的基本信息,例如所需的权限、名称、版本等。

当前配置清单类型最新的版本是 Manifest V3,遵循该配置清单版本的扩展程序会更注重安全和用户的隐私保护,在性能方面也会得到提升,同时开发简易性和功能实现也会更佳。

从 Chrome 88 版本开始支援配置清单为 Manifest V3 版本的扩展程序,Chrome 网上应用店从 2021 年 1 月开始支持分发配置清单为 Manifest V3 版本的扩展程序。

截屏2022-09-29 14.20.06.png

其中,manifest_version、name、version3个是必不可少的,description和icons是推荐的。

Manifest file format。

{ // Required "manifest_version": 3, "name": "My Extension", "version": "versionString", // Recommended "action": {...}, "default_locale": "en", "description": "A plain text description", "icons": {...}, // Optional "author": ..., "automation": ..., "background": { // Required "service_worker": "background.js", // Optional "type": ... }, "chrome_settings_overrides": {...}, "chrome_url_overrides": {...}, "commands": {...}, "content_capabilities": ..., "content_scripts": [{...}], "content_security_policy": {...}, "converted_from_user_script": ..., "cross_origin_embedder_policy": {"value": "require-corp"}, "cross_origin_opener_policy": {"value": "same-origin"}, "current_locale": ..., "declarative_net_request": ..., "devtools_page": "devtools.html", "differential_fingerprint": ..., "event_rules": [{...}], "externally_connectable": { "matches": ["*://*.example.com/*"] }, "file_browser_handlers": [...], "file_system_provider_capabilities": { "configurable": true, "multiple_mounts": true, "source": "network" }, "homepage_url": "https://path/to/homepage", "host_permissions": [...], "import": [{"id": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}], "incognito": "spanning, split, or not_allowed", "input_components": ..., "key": "publicKey", "minimum_chrome_version": "versionString", "nacl_modules": [...], "natively_connectable": ..., "oauth2": ..., "offline_enabled": true, "omnibox": { "keyword": "aString" }, "optional_host_permissions": ["..."], "optional_permissions": ["tabs"], "options_page": "options.html", "options_ui": { "page": "options.html" }, "permissions": ["tabs"], "platforms": ..., "replacement_web_app": ..., "requirements": {...}, "sandbox": [...], "short_name": "Short Name", "storage": { "managed_schema": "schema.json" }, "system_indicator": ..., "tts_engine": {...}, "update_url": "https://path/to/updateInfo.xml", "version_name": "aString", "web_accessible_resources": [...] } 复制代码 API 概览

Chrome为扩展提供了许多特殊用途的 API,例如 chrome.runtime 和 chrome.alarms。 可以通过API 参考查看Chrom extension提供的api

API 声明权限

要使用 chrome.* API,您的扩展程序必须在manifest的权限字段中声明。 扩展可以请求三类权限:

permissions 如 Storage optional_permissions 可选的权限 host_permissions 主机权限 实例: "permissions": [ "tabs", "bookmarks", "unlimitedStorage" ], "optional_permissions": [ "unlimitedStorage" ], "host_permissions": [ "http://www.blogger.com/", "http://*.google.com/" ], 复制代码

可通过权限列表查看哪些api需要注册权限

Service Workers

在 Manifest V2 版本中,后台页面 background pages 是扩展程序中的一个独立页面,一般设置事件监听,以响应用户的操作,但是它会长期驻留后台影响性能。

Service Workers 特点

在 Manifest V3 版本中,后台脚本迁移到 Service Workers 中运行以提供性能,其中有两个特点:

Service Workers 在执行事件处理函数后终止,并在新的事件触发下重新运行

它是一种 JavaScript Worker,无法直接访问 DOM。

💡 Service Worker 是浏览器完全独立于网页运行的脚本。除了以上的特点,还要注意以下的相关事项:

它是一种可编程网络代理,让您能够控制页面所发送网络请求的处理方式。

它广泛地利用了 promise 进行异步操作。

如果需要使用 service workers 时需要在配置清单 manifest.json 的选项 background.service_worker 中声明注册,属性值指定需要执行的一个 JavaScript 文档的路径(它必须在项目的根目录下)

{ "name": "Awesome Test Extension", ... "background": { "service_worker": "background.js", "type": "module" // }, ... } 复制代码 Service Workers注意事项 事件注册在Service Workers脚本的顶层 // background.js chrome.storage.local.get(["badgeText"], ({ badgeText }) => { chrome.action.setBadgeText({ text: badgeText }); chrome.action.onClicked.addListener(handleActionClick); }); // true chrome.action.onClicked.addListener(handleActionClick); 复制代码 Service Workers 基于监听事件-响应模型来执行。是 short-lived,有别于long-lived 在Manifest V2中: let savedName = undefined; chrome.runtime.onMessage.addListener(({ type, name }) => { if (type === "set-name") { savedName = name; } }); chrome.browserAction.onClicked.addListener((tab) => { chrome.tabs.sendMessage(tab.id, { name: savedName }); }); 复制代码

在Manifest V3中实现此功能,需要借助Storage APIs

// background.js chrome.runtime.onMessage.addListener(({ type, name }) => { if (type === "set-name") { chrome.storage.local.set({ name }); } }); chrome.action.onClicked.addListener((tab) => { chrome.storage.local.get(["name"], ({ name }) => { chrome.tabs.sendMessage(tab.id, { name }); }); }); 复制代码 在 Service Workers 中不能使用setTimeout or setInterval,这些 API 在Service Workers 中可能会失败,因为调度程序将在Service Workers终止时取消计时器 // background.js // This worked in Manifest V2. const TIMEOUT = 3 * 60 * 1000; // 3 minutes in milliseconds setTimeout(() => { chrome.action.setIcon({ path: getRandomIconPath(), }); }, TIMEOUT); 复制代码

需要使用Alarms API

// background.js chrome.alarms.create({ delayInMinutes: 3 }); chrome.alarms.onAlarm.addListener(() => { chrome.action.setIcon({ path: getRandomIconPath(), }); }); 复制代码 无权访问 DOM。Service Worker 不再提供 XMLHttpRequest,而是支持更现代的 fetch()。 Content scripts

Content scripts 是运行在web 上下文的脚本。

它可以访问页面的 DOM 对象,还可以以通过信息传递 message passing的方式与扩展程序进行通讯,可以将它看作是页面与扩展程序之间的桥梁角色。

Content scripts 可访问API

Content scripts可以直接访问以下 chrome API:

i18n

storage

runtime:

connect getManifest getURL id onConnect onMessage sendMessage 独立运行环境

内容脚本 content script 在一个独立的环境中执行(私有作用域),因此页面和扩展程序都无法访问内容脚本 content script 的变量,可以避免与页面或扩展程序的脚本发生冲突。 注入脚本

注入脚本

内容脚本可以静态声明或以编程方式注入

静态注入

静态声明的脚本在“content_scripts”字段下的清单中注册。它们可以包括 JavaScript 文件、CSS 文件或两者兼有。所有自动运行的内容脚本都必须指定匹配模式。

{ "name": "My extension", "content_scripts": [ { "matches": ["https://*.nytimes.com/*"], "css": ["my-styles.css"], "js": ["content-script.js"] } ], } 复制代码

content_scripts 字段中的值的含义

NameTypeDescriptionmatchesarray of stringsRequired.  cssarray of stringsOptional.  jsarray of stringsOptional.  match_about_blankbooleanOptional.  match_origin_as_fallbackbooleanOptional. 动态注入

动态注入脚本需要对应的主机权限和 scripting权限。

主机权限可以通过将它们作为扩展清单的一部分请求来授予(请参阅 host_permissions),也可以通过 activeTab 临时授予。

在配置清单 manifest.json 的选项 permissions 中声明 activeTab 权限,可以临时获取许可,以访问当前激活的标签页,并在当前页面使用 tabs 相关的 API。

由于扩展程序的很多使用场景都只需临时访问当前激活的标签页,而不是针对特定的网页,所以与基于 URL 规则获取的永久访问权限相比,该类型的权限更常用。该权限基于用户的主动请求临时获取的(例如通过点击 Action 控件),而且仅限制在当前激活页面,相对而言更安全。

示例:

{ "name": "My extension", ... "permissions": [ "activeTab" ], "background": { "service_worker": "background.js" } } 复制代码

background.js:

function injectedFunction() { document.body.style.backgroundColor = 'orange'; } chrome.action.onClicked.addListener((tab) => { chrome.scripting.executeScript({ target: { tabId: tab.id }, func: injectedFunction }); }); 复制代码

官方文档

源码参考:

通信 Message passing

由于内容脚本在网页上下文而不是扩展程序的上下文中运行,因此它们通常需要某种方式与扩展程序的其余部分进行通信。

Chrome 除了提供简单的 API 进行一次性的请求-响应通讯(one-time requests),也提供复杂的 API 进行长连接通讯(long-lived connections),还可以基于 ID 进行跨扩展程序的通讯。

Simple one-time requests

使用runtime.sendMessage or tabs.sendMessage 进行单次请求,这两个方法可以设置回调函数,默认接收返回的响应数据作为参数。 发送消息

// content script发送消息 chrome.runtime.sendMessage({greeting: "hello"}, function(response) { console.log(response.farewell); }); // 向content script中发送消息 chrome.tabs.query({active: true, currentWindow: true}, function(tabs) { chrome.tabs.sendMessage(tabs[0].id, {greeting: "hello"}, function(response) { console.log(response.farewell); }); }); 复制代码

接收方接收消息

chrome.runtime.onMessage.addListener( function(request, sender, sendResponse) { console.log(sender.tab ? "from a content script:" + sender.tab.url : "from the extension"); if (request.greeting === "hello") sendResponse({farewell: "goodbye"}); } ); 复制代码 Long-lived connections

可以使用runtime.connect or tabs.connect 为内容脚本 content script 和扩展程序之间建立一个长连接(可以为信息通道 channel 设置名称,以区别多个通道)。

使用以上方法创建通道后,会返回一个 runtime.Port 端口对象,其中包括了关于信息通道的相关方法和属性,然后就可以通过该通道发送 portObj.postMessage() 和接收 portObj.onMessage.addListener() 信息。

// 在页面脚本 content script 建立长连接的信息通道 let port = chrome.runtime.connect({name: "knockknock"}); // 通过该端口发送信息 port.postMessage({joke: "Knock knock"}); // 设置事件监听器,通过该端口接收信息,将接收到的信息作为入参 port.onMessage.addListener(function(msg) {  if (msg.question === "Who's there?")    port.postMessage({answer: "Madame"});  else if (msg.question === "Madame who?")    port.postMessage({answer: "Madame... Bovary"}); }); 复制代码

类似地,如果在扩展程序中建立长连接发送消息时,使用方法 chrome.tabs.connect(),需要指定请求是发送给哪个特定的 tab 标签页。

信息通道是双向的,因此除了发起端创建端口,还需要在接收端使用runtime.onConnect 响应通道连接请求(在内容脚本 content script 和扩展程序中一样)。当通道发起端口调用 connect 方法时,接收端的监听器就会调用回调函数,它将相应的 runtime.Port 端口对象作为入参,然后可以使用该端口在通道中发送和接收消息,这样通道两端的接口就可以相互接收和发送信息了。

chrome.runtime.onConnect.addListener(function(port) {  console.assert(port.name === "knockknock");  port.onMessage.addListener(function(msg) {    if (msg.joke === "Knock knock")      port.postMessage({question: "Who's there?"});    else if (msg.answer === "Madame")      port.postMessage({question: "Madame who?"});    else if (msg.answer === "Madame... Bovary")      port.postMessage({question: "I don't get it."}); }); }); 复制代码 Cross-origin XMLHttpRequest

常规网页可以使用 XMLHttpRequest 对象从远程服务器发送和接收数据,但它们受到同源策略的限制。

content script以植入网页的方式运行,因此content script本也受制于相同的源策略。 而扩展程序的后台脚本 background scripts 就不受此限制,只需要在 host_permissions 中声明后就可以访问相应的远程服务器;

如果是通过 fetch() 的方式获取扩展程序内部的静态资源,则不需要声明权限。

通过将主机或主机匹配模式(或两者)添加到清单文件的 host_permissions 部分,扩展可以请求访问其源之外的远程服务器。

声明主机权限 { "name": "My extension", ... "host_permissions": [ "https://www.google.com/" ], ... } 复制代码 发送跨域请求

由于内容脚本 content scripts 受到同源政策的限制,可以通过信息传递 message passing 借助扩展程序来 fetch 相应的服务器获取数据。

sendMessage 与后台脚本通信

chrome.runtime.sendMessage( {contentScriptQuery: 'queryPrice', itemId: 12345}, price => ...); 复制代码

后台脚本进行事件监听

chrome.runtime.onMessage.addListener( function(request, sender, sendResponse) { if (request.contentScriptQuery == 'queryPrice') { var url = 'https://www.google.com/?itemId=' + encodeURIComponent(request.itemId); fetch(url) .then(response => response.text()) .then(text => parsePrice(text)) .then(price => sendResponse(price)) .catch(error => ...) return true; // Will respond asynchronously. } }); 复制代码 chrome.alarms

使用 chrome.alarms API 使代码定期运行或在未来的指定时间运行。

要使用chrome.alarms.* API,首先需要在manifest.json文件中声明alarms授权如下:

{ "permissions": [ "alarms" ], } 复制代码 Alarm 类型

chrome.alarms.create()方法可以创建一个alarm,Alarm包含以下字段:

name ( string ) 该定时器的名称。 scheduledTime 该定时器计划的触发时间。由于性能原因,定时器可能会延迟至该时间后的任意时间。 periodInMinutes ( optional ) 如果不是 null 的话,该定时器会重复触发,每隔 periodInMinutes 分钟触发。 chrome.alarms 方法

chrome.alarms API中的常用方法:

创建一个alarm chrome.alarms.create(   name?: string,   alarmInfo: AlarmCreateInfo, ) 复制代码

AlarmCreateInfo 类型说明:

delayInMinutes: onAlarm 事件应该触发的时间长度(以分钟为单位) periodInMinutes: 指定重复触发的时间间隔,如果未设置,则警报只会触发一次。 when: 警报应该触发的时间,以历元过去的毫秒数为单位(例如 Date.now() + n) 获取指定名字的alarm chrome.alarms.get(   name?: string,   callback?: function, ) 复制代码 获取所有alarm chrome.alarms.getAll(   callback?: function, ) 复制代码 通过名字删除alarm chrome.alarms.clear(   name?: string,   callback?: function, ) 复制代码 清除所有alarm chrome.alarms.clearAll(   callback?: function, ) 复制代码

监听alarm发生的事件,用于event page

chrome.alarms.onAlarm.addListener(   callback: function, ) 复制代码

回调函数中的alarm就是触发事件的alarm对象。

Storage

该 API 已经过优化以满足扩展的特定存储需求。它提供与 localStorage API 相同的存储功能,但主要区别如下:

使用 chrome.storage.sync 相关方法,就可以利用 Chrome 的同步功能,实现同一账户下的扩展程序数据在多个设备之间同步 批量的读取和写入数据操作是异步执行的,因此与 localStorage 引起的阻塞和串行相比操作更快 存储的数据类型可以是对象,而 localStorage 只允许存储字符串 使用

先声明权限

{ "name": "My extension", ... "permissions": [ "storage" ], ... } 复制代码 sync 同步存储 chrome.storage.sync.set({key: value}, function() { console.log('Value is set to ' + value); }); chrome.storage.sync.get(['key'], function(result) { console.log('Value currently is ' + result.key); }); 复制代码 本地存储 chrome.storage.local.set({key: value}, function() { console.log('Value is set to ' + value); }); chrome.storage.local.get(['key'], function(result) { console.log('Value currently is ' + result.key); }); 复制代码 参考

Storage API 参考

UI

与 Chrome 的用户界面 (UI) 一样,extension UI 应该是有目的的和最小的。extension允许用户自定义或增强用户的浏览体验,而不会分散注意力。

action

Action API 控制extension的操作(工具栏图标)。它可以在单击时打开一个popup或当点击的时候触发某些功能。 截屏2022-10-13 10.59.01.png 要使用 Action API,manifest必须包含一个“action”键。

{ "name": "My Awesome action MV3 Extension", ... "action": { ... } ... } 复制代码

通过default_icon 字段设置extension 位于工具栏右侧 的icon。可以设置多个尺寸的图片

{ "name": "My Awesome Extension", ... "action": { "default_icon": { "16": "extension_toolbar_icon16.png", "32": "extension_toolbar_icon32.png" } } ... } 复制代码 icons

可以通过manifest 中的icons字段设置工具栏以外的其他icon

"icons": { "16": "extension_icon16.png", "32": "extension_icon32.png", "48": "extension_icon48.png", "128": "extension_icon128.png" } 复制代码 Icon SizeIcon Use16x16extension pages 和上下问菜单中的icon32x32Windows 计算机通常需要这种尺寸48x48extension 管理页面中展示128x128Chrome Web Store 展示 其他用户界面功能 Action badge

Action badge 在操作图标顶部显示彩色banner

截屏2022-10-13 11.33.23.png

可以使用以下api设置:

chrome.action.setBadgeText({text: '14'}); chrome.action.setBadgeBackgroundColor({color: '#4688F1'}); 复制代码 Popup

Popup是HTML文件,当点击action icon时可以展示该页面。

它可以包含样式表和脚本标签的链接,但不允许内联 JavaScript。 popup在“action”键下的清单中注册

{ "name": "Drink Water Event", ... "action": { "default_popup": "popup.html" } ... } 复制代码

也可以通过action.setPopup 动态设置

chrome.storage.local.get('signed_in', (data) => { if (data.signed_in) { chrome.action.setPopup({popup: 'popup.html'}); } else { chrome.action.setPopup({popup: 'popup_sign_in.html'}); } }); 复制代码 Tooltip

将鼠标悬停在操作图标上时,使用Tooltip向用户提供简短描述或说明。

截屏2022-10-13 11.52.28.png

{ "name": "Tab Flipper", ... "action": { "default_title": "学习chrome extension 演示demo" } ... } 复制代码 Click Event

通过 action.onClicked.addListener给action注册点击事件,但是如果设置了popup不会生效

chrome.action.onClicked.addListener(function(tab) { chrome.action.setTitle({tabId: tab.id, title: "You are on tab:" + tab.id}); }); 复制代码 Omnibox { "name": "Omnibox New Tab Search", ... "omnibox": { "keyword" : "nt" }, "default_icon": { "16": "newtab_search16.png", "32": "newtab_search32.png" } ... } 复制代码 Context menu

可以使用ContextMenus API 设置 Context menu。 现在manifest中注册 contextMenus权限

{ "permissions": [ "contextMenus", ] } 复制代码

通过contextMenus.create()创建 Context menu。通常在runtime.onInstalled 的回调函数中完成

chrome.runtime.onInstalled.addListener(async () => { for (let [tld, locale] of Object.entries(tldLocales)) { chrome.contextMenus.create({ id: tld, title: locale, type: 'normal', contexts: ['selection'], }); } }); 复制代码 Commands

扩展可以定义特定的 Commands API 并将它们绑定到一个组合键。在“commands”键下的清单中注册一个或多个快捷方式

{ "commands": { "go-google": { "suggested_key": { "default": "Ctrl+Shift+L", "mac": "Command+Shift+L" }, "description": "谷歌" }, "go-baidu": { "suggested_key": { "default": "Ctrl+Shift+P", "mac": "Command+Shift+P" }, "description": "百度" } } } 复制代码

然后在 service worker中通过进行事件监听:

chrome.commands.onCommand.addListener(command => { if (command === 'go-google') { chrome.tabs.create({ url: "https://www.google.com" }); } else { chrome.tabs.create({ url: "https://www.baidu.com" }); } }); 复制代码

参考:developer.chrome.com/docs/extens…

Override pages

extension 允许用户通过Override pages历替换史记录、新选项卡或书签页面, 像popup一样,但不允许内联 JavaScript。

在manifestchrome_url_overrides字段中注册覆盖页面,只能注册一个页面

{ "name": "Awesome Override Extension", ... "chrome_url_overrides" : { "newtab": "override_page.html", // "history": "history.html" }, ... } 复制代码 Notifications

您可以通过直接在系统托盘中显示通知来向用户传达相关信息 需要先注册 notifications 权限:

// manifest.json { "name": "Drink Water Event Popup", ... "permissions": [ "alarms", "notifications", "storage" ], ... } 复制代码

调用notifications.create发送通知:

chrome.notifications.create({ type: 'basic', iconUrl: 'popup/stay_hydrated.png', title: '温馨提示', message: '太累了就休息会儿吧', buttons: [ { title: '好的' } ], priority: 0 }); 复制代码 History

使用 chrome.history API可以操作浏览器访问过的页面记录。

可以在浏览器的历史记录中添加,删除和查询URL

权限申请 "permissions": ["history"] 复制代码 方法使用 chrome.history.search(object query, function callback) 在历史记录中搜索与查询匹配的每个页面的上次访问记录

注意 query 参数,text 字段是必不可少的,但是 text 可以留空,相当于一个 keyword

const query = { text: '' }; chrome.history.search(query, (res) => { console.log(res); }) 复制代码 chrome.history.getVisits(object details, function callback) 检索某个 URL 的访问信息 const details = { url: 'http://www.baidu.com' }; chrome.history.getVisits(details, (res) => { const arr = res.slice(0,3).map((item) => { return item }); let htm = ''; arr.forEach(element => { htm += `

transition: ${element.transition}

`; }); document.querySelector('#scroll').innerHTML = htm; }) 复制代码 chrome.history.addUrl(object details, function callback) 使用 transition type link 向历史记录中添加一条记录 const details = { url: 'http://ptbird.cn/chrome_extensions_aaa_2-s_as' }; chrome.history.addUrl(details, (res) => { console.log(res); }) 复制代码 chrome.history.deleteUrl(object details, function callback) 从历史记录中删除所有出现的给定URL const details = { url: 'http://www.baidu.com' }; chrome.history.deleteUrl(details, (res) => { console.log(res); }) 复制代码 chrome.history.deleteRange(object range, function callback) 从历史记录中删除指定日期范围内的所有项目。除非所有访问都在此范围内,否则页面不会从历史记录中删除。 const startTime = Date.now() - 50000; const endTime = Date.now(); const query = { startTime, endTime }; chrome.history.deleteRange(query, (res) => { console.log(res); }) ```Javascript 6、chrome.history.deleteAll(function callback) 删除历史记录中的所有项目。 ```Javascript chrome.history.deleteAll((res) => { console.log(res); }) 复制代码 Bookmarks

使用 chrome.bookmarks 能够创建、组织和操作书签,能够自定义操作书签的页面。

权限申请

如果要使用 chrome.bookmarks 需要在 manifest 的 permissions 中增加 bookmarks 权限申请。

"permissions": ["tabs", "bookmarks", "storage"] 复制代码 书签组织形式

书签以树形式组织,树中的每个节点都是书签或文件夹(有时称为组)。

树中的每个节点都由 bookmarks.BookmarkTreeNode 对象表示。

整个 chrome.bookmarks API 都是使用 BookmarkTreeNode 属性。例如,当调用 bookmarks.create 时,传入新节点的父节点(parentId),并且可以选择传入节点的索引、标题和 URL 属性。

注意:无法使用 chrome.bookmarks API 添加或删除根文件夹中的条目。无法重命名、移动或删除特殊的 “书签栏” 和 “其他” 文件夹。

方法示例 chrome.bookmarks.getTree(function callback) 获取整个书签栏的树 btn1.onclick = () => { chrome.bookmarks.getTree((res) => { console.log(res); }) }; 复制代码 chrome.bookmarks.getSubTree(string id, function callback) 获取某个节点的子树 btn2.onclick = () => { chrome.bookmarks.getSubTree(tree[0].children[0].children[0].id, (res) => { console.log(res); }) }; 复制代码 chrome.bookmarks.get(string or array of string idOrIdList, function callback) 获取节点信息

需要注意的是,无论是什么 get 方法,每次都是返回一个 Array 类型,即使请求的是节点,返回的也是 Array

btn3.onclick = () => { chrome.bookmarks.get("5", (res) => { console.log(res); }) }; 复制代码 chrome.bookmarks.getChildren(string id, function callback) 获取所有的子节点 btn4.onclick = () => { chrome.bookmarks.getChildren("5", (res) => { console.log(res); }) }; 复制代码 chrome.bookmarks.getRecent(integer numberOfItems, function callback) 获取最近的书签 btn5.onclick = () => { chrome.bookmarks.getRecent(5, (res) => { console.log(res); }) }; 复制代码 chrome.bookmarks.search(string or object query, function callback) 搜索书签 postbird search btn6.onclick = () => { const value = document.querySelector('#textarea').value; chrome.bookmarks.search(value, (res) => { console.log(res); }) }; 复制代码 chrome.bookmarks.create(object bookmark, function callback) 创建一个书签,在指定的 parentId 下创建书签或文件夹。如果 url 为N ULL 或没有该字段,会创建一个文件夹。 btn7.onclick = () => { const title = document.querySelector('#title').value; const url = document.querySelector('#url').value; const obj = { parentId: '5', title, url, } chrome.bookmarks.create(obj, (res) => { console.log(res); }) }; 复制代码 chrome.bookmarks.move(string id, object destination, function callback) 移动书签,注意不能移动到 0 这个 root 节点中,因为不允许任何修改 root 节点的行为 btn8.onclick = () => { const dest = { parentId: '1' } chrome.bookmarks.move('48', dest, (res) => { console.log(res); }) }; 复制代码 chrome.bookmarks.update(string id, object changes, function callback) 更新书签或文件夹的属性。仅指定要更改的属性; 未指定的属性将保持不变。注意:**目前,仅支持 title 和 url。 btn9.onclick = () => { const title = document.querySelector('#titleUpdate').value; const url = document.querySelector('#urlUpdate').value; const obj = { title, url, } chrome.bookmarks.update('48', obj, (res) => { console.log(res); }) }; 复制代码 chrome.bookmarks.remove(string id, function callback) 删除书签或空书签文件夹。 chrome.bookmarks.remove('48', (res) => { console.log(res); }) 复制代码

11、chrome.bookmarks.removeTree(string id, function callback) 删除整个书签树

chrome.bookmarks.removeTree('5', (res) => { console.log(res); }) 复制代码

参考:

小茗同学

官网



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有