chrome插件开发的几种展现页面形式,3分钟看完

想要开发一个chrome浏览器插件,还是很有必要清楚插件都可以在哪些地方显示出来的,比如只想在pop页面弹出,还是添加右键菜单,还是提示桌面通知?还是在哪里展示?有哪些展示方式等

browserAction(浏览器右上角)

通过配置browser_action可以在浏览器的右上角增加一个图标,一个browser_action可以拥有一个图标,一个tooltip,一个badge和一个popup。

示例配置如下: 

"browser_action":
{"default_icon": "img/icon.png","default_title": "这是一个示例Chrome插件","default_popup": "popup.html"
}

图标

browser_action图标推荐使用宽高都为19像素的图片,更大的图标会被缩小,格式随意,一般推荐png,可以通过manifest中default_icon字段配置,也可以调用setIcon()方法。

tooltip

修改browser_action的manifest中default_title字段,或者调用setTitle()方法。

badge

所谓badge就是在图标上显示一些文本,可以用来更新一些小的扩展状态提示信息。因为badge空间有限,所以只支持4个以下的字符(英文4个,中文2个)。badge无法通过配置文件来指定,必须通过代码实现,设置badge文字和颜色可以分别使用setBadgeText()setBadgeBackgroundColor()

chrome.browserAction.setBadgeText({text: 'new'});
chrome.browserAction.setBadgeBackgroundColor({color: [255, 0, 0, 255]});

效果:

 

pageAction(地址栏右侧) 

所谓pageAction,指的是只有当某些特定页面打开才显示的图标,它和browserAction最大的区别是一个始终都显示,一个只在特定情况才显示。

需要特别说明的是早些版本的Chrome是将pageAction放在地址栏的最右边,左键单击弹出popup,右键单击则弹出相关默认的选项菜单:

而新版的Chrome更改了这一策略,pageAction和普通的browserAction一样也是放在浏览器右上角,只不过没有点亮时是灰色的,点亮了才是彩色的,灰色时无论左键还是右键单击都是弹出选项。

调整之后的pageAction我们可以简单地把它看成是可以置灰的browserAction

  • chrome.pageAction.show(tabId) 显示图标;
  • chrome.pageAction.hide(tabId) 隐藏图标;

示例(只有打开百度才显示图标):

// manifest.json
{"page_action":{"default_icon": "img/icon.png","default_title": "我是pageAction","default_popup": "popup.html"},"permissions": ["declarativeContent"]
}
// background.js
chrome.runtime.onInstalled.addListener(function(){chrome.declarativeContent.onPageChanged.removeRules(undefined, function(){chrome.declarativeContent.onPageChanged.addRules([{conditions: [// 只有打开百度才显示pageActionnew chrome.declarativeContent.PageStateMatcher({pageUrl: {urlContains: 'baidu.com'}})],actions: [new chrome.declarativeContent.ShowPageAction()]}]);});
});

效果图:

pageAction(地址栏右侧) - 图3

 

侧板UI

可以给网页侧边添加相应的一个UI或者组件展示出来,也可以通过content.js脚本修改页面元素来达到目的,可以看官方文档:https://developer.chrome.com/docs/extensions/develop/ui?hl=zh-cn

如需了解如何构建侧边栏,请参阅侧边栏用例,或查看侧边栏示例。 

 

右键菜单

通过开发Chrome插件可以自定义浏览器的右键菜单,主要是通过chrome.contextMenusAPI实现,右键菜单可以出现在不同的上下文,比如普通页面、选中的文字、图片、链接,等等,如果有同一个插件里面定义了多个菜单,Chrome会自动组合放到以插件名字命名的二级菜单里,如下:

右键菜单 - 图1

最简单的右键菜单示例

// manifest.json
{"permissions": ["contextMenus"]}
// background.js
chrome.contextMenus.create({title: "测试右键菜单",onclick: function(){alert('您点击了右键菜单!');}
});

效果:

右键菜单 - 图2

添加右键百度搜索

// manifest.json
{"permissions": ["contextMenus", "tabs"]}
// background.js
chrome.contextMenus.create({title: '使用度娘搜索:%s', // %s表示选中的文字contexts: ['selection'], // 只有当选中文字时才会出现此右键菜单onclick: function(params){// 注意不能使用location.href,因为location是属于background的window对象chrome.tabs.create({url: 'https://www.baidu.com/s?ie=utf-8&wd=' + encodeURI(params.selectionText)});}
});

效果如下:

右键菜单 - 图3

语法说明

这里只是简单列举一些常用的,完整API参见:https://developer.chrome.com/extensions/contextMenus

chrome.contextMenus.create({type: 'normal', // 类型,可选:["normal", "checkbox", "radio", "separator"],默认 normaltitle: '菜单的名字', // 显示的文字,除非为“separator”类型否则此参数必需,如果类型为“selection”,可以使用%s显示选定的文本contexts: ['page'], // 上下文环境,可选:["all", "page", "frame", "selection", "link", "editable", "image", "video", "audio"],默认pageonclick: function(){}, // 单击时触发的方法parentId: 1, // 右键菜单项的父菜单项ID。指定父菜单项将会使此菜单项成为父菜单项的子菜单documentUrlPatterns: 'https://*.baidu.com/*' // 只在某些页面显示此右键菜单
});
// 删除某一个菜单项
chrome.contextMenus.remove(menuItemId);
// 删除所有自定义右键菜单
chrome.contextMenus.removeAll();
// 更新某一个菜单项
chrome.contextMenus.update(menuItemId, updateProperties);

override(覆盖特定页面)

使用override页可以将Chrome默认的一些特定页面替换掉,改为使用扩展提供的页面。

扩展可以替代如下页面:

  • 历史记录:从工具菜单上点击历史记录时访问的页面,或者从地址栏直接输入chrome://history
  • 新标签页:当创建新标签的时候访问的页面,或者从地址栏直接输入chrome://newtab
  • 书签:浏览器的书签,或者直接输入chrome://bookmarks

注意:

  • 一个扩展只能替代一个页面;
  • 不能替代隐身窗口的新标签页;
  • 网页必须设置title,否则用户可能会看到网页的URL,造成困扰;

下面的截图是默认的新标签页和被扩展替换掉的新标签页。

override(覆盖特定页面) - 图1

代码(注意,一个插件只能替代一个默认页,以下仅为演示):

"chrome_url_overrides":
{"newtab": "newtab.html","history": "history.html","bookmarks": "bookmarks.html"
}

devtools(开发者工具) 

使用过vue的应该见过这种类型的插件:

devtools(开发者工具) - 图1

是的,Chrome允许插件在开发者工具(devtools)上动手脚,主要表现在:

  • 自定义一个和多个和ElementsConsoleSources等同级别的面板;
  • 自定义侧边栏(sidebar),目前只能自定义Elements面板的侧边栏;

先来看2张简单的demo截图,自定义面板(判断当前页面是否使用了jQuery):

devtools(开发者工具) - 图2

自定义侧边栏(获取当前页面所有图片):

devtools(开发者工具) - 图3

devtools扩展介绍

主页:https://developer.chrome.com/extensions/devtools

来一张官方图片:

devtools(开发者工具) - 图4

每打开一个开发者工具窗口,都会创建devtools页面的实例,F12窗口关闭,页面也随着关闭,所以devtools页面的生命周期和devtools窗口是一致的。devtools页面可以访问一组特有的DevTools API以及有限的扩展API,这组特有的DevTools API只有devtools页面才可以访问,background都无权访问,这些API包括:

  • chrome.devtools.panels:面板相关;
  • chrome.devtools.inspectedWindow:获取被审查窗口的有关信息;
  • chrome.devtools.network:获取有关网络请求的信息;

大部分扩展API都无法直接被DevTools页面调用,但它可以像content-script一样直接调用chrome.extensionchrome.runtimeAPI,同时它也可以像content-script一样使用Message交互的方式与background页面进行通信。

实例:创建一个devtools扩展

首先,要针对开发者工具开发插件,需要在清单文件声明如下:

{// 只能指向一个HTML文件,不能是JS文件"devtools_page": "devtools.html"
}

这个devtools.html里面一般什么都没有,就引入一个js:

<!DOCTYPE html>
<html>
<head></head>
<body><script type="text/javascript" src="js/devtools.js"></script>
</body>
</html>

可以看出来,其实真正代码是devtools.js,html文件是“多余”的,所以这里觉得有点坑,devtools_page干嘛不允许直接指定JS呢?

再来看devtools.js的代码:

// 创建自定义面板,同一个插件可以创建多个自定义面板
// 几个参数依次为:panel标题、图标(其实设置了也没地方显示)、要加载的页面、加载成功后的回调
chrome.devtools.panels.create('MyPanel', 'img/icon.png', 'mypanel.html', function(panel)
{console.log('自定义面板创建成功!'); // 注意这个log一般看不到
});
// 创建自定义侧边栏
chrome.devtools.panels.elements.createSidebarPane("Images", function(sidebar)
{// sidebar.setPage('../sidebar.html'); // 指定加载某个页面sidebar.setExpression('document.querySelectorAll("img")', 'All Images'); // 通过表达式来指定//sidebar.setObject({aaa: 111, bbb: 'Hello World!'}); // 直接设置显示某个对象
});

setPage时的效果:

devtools(开发者工具) - 图5

以下截图示例的代码:

devtools(开发者工具) - 图6

 

// 检测jQuery
document.getElementById('check_jquery').addEventListener('click', function()
{// 访问被检查的页面DOM需要使用inspectedWindow// 简单例子:检测被检查页面是否使用了jQuerychrome.devtools.inspectedWindow.eval("jQuery.fn.jquery", function(result, isException){var html = '';if (isException) html = '当前页面没有使用jQuery。';else html = '当前页面使用了jQuery,版本为:'+result;alert(html);});
});
// 打开某个资源
document.getElementById('open_resource').addEventListener('click', function()
{chrome.devtools.inspectedWindow.eval("window.location.href", function(result, isException){chrome.devtools.panels.openResource(result, 20, function(){console.log('资源打开成功!');});});
});
// 审查元素
document.getElementById('test_inspect').addEventListener('click', function()
{chrome.devtools.inspectedWindow.eval("inspect(document.images[0])", function(result, isException){});
});
// 获取所有资源
document.getElementById('get_all_resources').addEventListener('click', function()
{chrome.devtools.inspectedWindow.getResources(function(resources){alert(JSON.stringify(resources));});
});

调试技巧

修改了devtools页面的代码时,需要先在 chrome://extensions 页面按下Ctrl+R重新加载插件,然后关闭再打开开发者工具即可,无需刷新页面(而且只刷新页面不刷新开发者工具的话是不会生效的)。

由于devtools本身就是开发者工具页面,所以几乎没有方法可以直接调试它,直接用chrome-extension://extid/devtools.html"的方式打开页面肯定报错,因为不支持相关特殊API,只能先自己写一些方法屏蔽这些错误,调试通了再放开。

option(选项页)

所谓options页,就是插件的设置页面,有2个入口,一个是右键图标有一个“选项”菜单,还有一个在插件管理页面:

 

在Chrome40以前,options页面和其它普通页面没什么区别,Chrome40以后则有了一些变化。

我们先看老版的options:

{// Chrome40以前的插件配置页写法"options_page": "options.html",
}

这个页面里面的内容就随你自己发挥了,配置之后在插件管理页就会看到一个选项按钮入口,点进去就是打开一个网页,没啥好讲的。

效果:

再来看新版的optionsV2:

{"options_ui":{"page": "options.html",// 添加一些默认的样式,推荐使用"chrome_style": true},
}

options.html的代码我们没有任何改动,只是配置文件改了,之后效果如下:

 

看起来是不是高大上了?

几点注意:

  • 为了兼容,建议2种都写,如果都写了,Chrome40以后会默认读取新版的方式;
  • 新版options中不能使用alert;
  • 数据存储建议用chrome.storage,因为会随用户自动同步;

omnibox

 

omnibox是向用户提供搜索建议的一种方式。先来看个gif图以便了解一下这东西到底是个什么鬼:

omnibox - 图1

注册某个关键字以触发插件自己的搜索建议界面,然后可以任意发挥了。

首先,配置文件如下:

{// 向地址栏注册一个关键字以提供搜索建议,只能设置一个关键字"omnibox": { "keyword" : "go" },
}

然后background.js中注册监听事件:

// omnibox 演示
chrome.omnibox.onInputChanged.addListener((text, suggest) => {console.log('inputChanged: ' + text);if(!text) return;if(text == '美女') {suggest([{content: '中国' + text, description: '你要找“中国美女”吗?'},{content: '日本' + text, description: '你要找“日本美女”吗?'},{content: '泰国' + text, description: '你要找“泰国美女或人妖”吗?'},{content: '韩国' + text, description: '你要找“韩国美女”吗?'}]);}else if(text == '微博') {suggest([{content: '新浪' + text, description: '新浪' + text},{content: '腾讯' + text, description: '腾讯' + text},{content: '搜狐' + text, description: '搜索' + text},]);}else {suggest([{content: '百度搜索 ' + text, description: '百度搜索 ' + text},{content: '谷歌搜索 ' + text, description: '谷歌搜索 ' + text},]);}
});
// 当用户接收关键字建议时触发
chrome.omnibox.onInputEntered.addListener((text) => {console.log('inputEntered: ' + text);if(!text) return;var href = '';if(text.endsWith('美女')) href = 'http://image.baidu.com/search/index?tn=baiduimage&ie=utf-8&word=' + text;else if(text.startsWith('百度搜索')) href = 'https://www.baidu.com/s?ie=UTF-8&wd=' + text.replace('百度搜索 ', '');else if(text.startsWith('谷歌搜索')) href = 'https://www.google.com.tw/search?q=' + text.replace('谷歌搜索 ', '');else href = 'https://www.baidu.com/s?ie=UTF-8&wd=' + text;openUrlCurrentTab(href);
});
// 获取当前选项卡ID
function getCurrentTabId(callback)
{chrome.tabs.query({active: true, currentWindow: true}, function(tabs){if(callback) callback(tabs.length ? tabs[0].id: null);});
}
// 当前标签打开某个链接
function openUrlCurrentTab(url)
{getCurrentTabId(tabId => {chrome.tabs.update(tabId, {url: url});})
}

桌面通知 

Chrome提供了一个chrome.notificationsAPI以便插件推送桌面通知,暂未找到chrome.notifications和HTML5自带的Notification的显著区别及优势。

在后台JS中,无论是使用chrome.notifications还是Notification都不需要申请权限(HTML5方式需要申请权限),直接使用即可。

最简单的通知:

代码:

chrome.notifications.create(null, {type: 'basic',iconUrl: 'img/icon.png',title: '这是标题',message: '您刚才点击了自定义右键菜单!'
});

通知的样式可以很丰富:

桌面通知 - 图2

这个没有深入研究,有需要的可以去官方文档查看更多细节。

5种类型的JS对比

 Chrome插件的JS主要可以分为这5类:injected scriptcontent-scriptpopup jsbackground jsdevtools js

调试方式对比

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/272540.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

免费下载Corel Video Studio 2024-轻松创建令人惊叹的视频!

免费下载Corel Video Studio 2024-轻松创建令人惊叹的视频&#xff01; Corel Video Studio 2024免费下载Keygen 你厌倦了在视频编辑软件上花大钱吗&#xff1f;别再看了&#xff01;我们为您提供了完美的解决方案——Corel Video Studio 2024。最棒的部分是什么&#xff1f;…

分享MDN前端结构化技能、实践指南、学习资源

前言 MDN课程为成为一名成功的前端开发人员提供了一个结构化的基本技能和实践指南&#xff0c;以及推荐的学习资源。 先看下让人不得不服的书《宝宝的网页设计》&#xff08;套装共3册&#xff09; 宝宝的HTML、宝宝的CSS、宝宝的JavaScript 全球首套中英文宝宝编程启蒙书&a…

计算机网络 八股

计算机网络体系结构 OSI&#xff1a;物理层、数据链路层、网络层、运输层、会话层、表示层、应用层

鸿蒙Harmony应用开发—ArkTS声明式开发(基础手势:Gauge)

数据量规图表组件&#xff0c;用于将数据展示为环形图表。 说明&#xff1a; 该组件从API Version 8开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 子组件 可以包含单个子组件。 说明&#xff1a; 建议使用文本组件构建当前数值文本和辅…

【xv6操作系统】xv6 启动过程分析

一、调试用到的汇编代码 为了方便&#xff0c; Makefile 会创建.asm 文件&#xff0c;可以通过它来定位究竟是哪个指令导致了 bug。 可以看到&#xff0c; kernel 从 80000000 地址处开始执行&#xff0c;第二列为相应指令&#xff08;如 auipc&#xff09; 的 16 进制表示&a…

缩放算法优化步骤详解

添加链接描述 背景 假设数据存放在在unsigned char* m_pData 里面&#xff0c;宽和高分别是&#xff1a;m_nDataWidth m_nDataHeight 给定缩放比例&#xff1a;fXZoom fYZoom&#xff0c;返回缩放后的unsigned char* dataZoom 这里采用最简单的缩放算法即&#xff1a; 根据比…

猫头虎分享已解决Bug || 系统监控故障:MonitoringServiceDown, MetricsCollectionError

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

如何在一个pycharm项目中创建jupyter notebook文件,并切换到conda环境中

1、第一步可以直接在pycharm项目中创建jupyter notebook文件 2、假若想要切换成pytorch环境做实验例子&#xff0c;会发现报这个错误 Jupyter server process exited with code 1 C:\Users\12430\.conda\envs\pytorch3.11\python.exe: No module named jupyter在这里&#xff…

Python快速入门系列-2(Python的安装与环境设置)

第二章&#xff1a;Python的安装与环境设置 2.1 Python的下载与安装2.1.1 访问Python官网2.1.2 安装Python对于Windows用户对于macOS用户对于Linux用户 2.2 集成开发环境&#xff08;IDE&#xff09;的选择与设置2.2.1 PyCharm2.2.2 Visual Studio Code2.2.3 Jupyter Notebook2…

jvm堆概述

《java虚拟机规范》中对java堆的描述是&#xff1a;所有的对象实例以及数组都应当在运行时分配在堆上。 一个JVM实例只存在一个堆内存(就是new 出来一个对象)&#xff0c;java内存管理的核心区域 java堆区在jvm启动的时候就被创建&#xff0c;空间大小确定。是jvm管理的最大一…

力扣--滑动窗口438.找到字符串中所有字母异位词

思路分析&#xff1a; 使用两个数组snum和pnum分别记录字符串s和p中各字符出现的次数。遍历字符串p&#xff0c;统计其中各字符的出现次数&#xff0c;存储在pnum数组中。初始化snum数组&#xff0c;统计s的前m-1个字符的出现次数。从第m个字符开始遍历s&#xff0c;通过滑动窗…

STM32_3-1点亮LED灯与蜂鸣器发声

STM32之GPIO GPIO在输出模式时可以控制端口输出高低电平&#xff0c;用以驱动Led蜂鸣器等外设&#xff0c;以及模拟通信协议输出时序等。 输入模式时可以读取端口的高低电平或电压&#xff0c;用于读取按键输入&#xff0c;外接模块电平信号输入&#xff0c;ADC电压采集灯 GP…

C# WinForm AndtUI第三方库 Table控件使用记录

环境搭建 1.在NuGet中搜索AndtUI并下载至C# .NetFramework WinForm项目。 2.添加Table控件至窗体。 使用方法集合 1.单元格点击事件 获取被点击记录特定列内容 private void dgv_CellClick(object sender, MouseEventArgs args, object record, int rowIndex, int columnIn…

一篇搞懂什么是LRU缓存|一篇搞懂LRU缓存的实现|LRUCache详解和实现

LRUCache 文章目录 LRUCache前言项目代码仓库什么时候会用到缓存(Cache)缓存满了&#xff0c;怎么办&#xff1f;什么是LRUCacheLRUCache的实现LRUCache对应的OJ题实现LRUCache对应的STL风格实现 前言 这里分享我的一些博客专栏&#xff0c;都是干货满满的。 手撕数据结构专栏…

解决ts报错:类型“entry”上不存在属性“$AppTools”

uniapp ts 项目&#xff0c;已经将AppTools挂在了vue的原型上&#xff0c;但是在vue页面使用时报错&#xff0c;如图&#xff1a; 解决&#xff1a; 在项目根目录下的tsconfig.json文件添加如下配置&#xff1a; "include": ["src/**/*"],这样报错就消失…

ChatGPT数据分析应用——热力图分析

ChatGPT数据分析应用——热力图分析 ​ 热力图分析既可以算作一种可视化方法&#xff0c;也可以算作一种分析方法&#xff0c;主要用于直观地展示数据的分布情况。接下来我们让ChatGPT解释这个方法的概念并提供相应的案例。发送如下内容给ChatGPT。 ​ ChatGPT收到上述内容后&…

云计算科学与工程实践指南--章节引言收集

云计算科学与工程实践指南–章节引言收集 //本文收集 【云计算科学与工程实践指南】 书中每一章节的引言。 我已厌倦了在一本书中阅读云的定义。难道你不失望吗&#xff1f;你正在阅读一个很好的故事&#xff0c;突然间作者必须停下来介绍云。谁在乎云是什么&#xff1f; 通…

opengl 学习(二)-----你好,三角形

你好&#xff0c;三角形 分类demo效果解析 分类 opengl c demo #include "glad/glad.h" #include "glfw3.h" #include <iostream> #include <cmath> #include <vector>using namespace std;/** * 在学习此节之前&#xff0c;建议将这…

MIT6.828操作系统工程实验学习笔记(二)

前言 这篇文章是接上文的内容&#xff0c;依然是对Lab1的记录 如何启动保护模式 要启动保护模式&#xff0c;需要完成以下三个步骤&#xff1a; 在内存中加载GDT&#xff0c;设置GDTR设置CR0寄存器的PE&#xff08;Protected Enable&#xff09;位&#xff0c;启用保护模式…

【深度学习笔记】6_9 深度循环神经网络deep-rnn

注&#xff1a;本文为《动手学深度学习》开源内容&#xff0c;部分标注了个人理解&#xff0c;仅为个人学习记录&#xff0c;无抄袭搬运意图 6.9 深度循环神经网络 本章到目前为止介绍的循环神经网络只有一个单向的隐藏层&#xff0c;在深度学习应用里&#xff0c;我们通常会用…