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.mzph.cn/news/732011.shtml

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

相关文章

原油数据处理:1.聚类、盐含量测定与近红外光谱快速评估

一、原油种类的聚类分析 在塔里木盆地塔河油田的原油处理过程中&#xff0c;需要对原油进行地球化学特征研究&#xff0c;以了解其成因和特征。根据地球化学手段的综合研究结果&#xff0c;塔河油田奥陶系原油属于海相沉积环境&#xff0c;成熟度较高&#xff0c;正构烷烃分布…

内存映射实现父子进程通信

创建内存映射区&#xff1a; void *mmap(void *addr ,size_t length,int prot,int flags,int fd,off_t offset); 参数&#xff1a; addr 指定映射区的首地址。通常NULL&#xff0c;表示让系统自动分配length 共享内存映射区的长度prot 共享内存的读写属性 PROT_READ PR…

【记录37】VueBaiduMap 踩坑一

截图 错误 Error in callback for watcher “position.lng”: “TypeError: Cannot read properties of undefined (reading ‘setPosition’)” 解释 回调观察程序“content”时出错&#xff1a;“TypeError:无法读取未定义的属性&#xff08;读取’setContent’&#xff09;”…

数据结构:Heap(二叉树)的基本操作

目录 1.有关二叉树必须知道的几个基本概念 2.有关二叉树的基本操作 2.0有关元素的定义以及要进行的操作 2.1初始化和销毁操作 2.2插入操作以及上调操作 2.2.1插入操作以及上调操作的图解 2.2.2插入操作以及上调操作的代码 2.3删除根元素及其下调操作 2.3.2删除根元素及…

Android studio Gradle下载失败,如何手动配置解决该问题详解

前些天发现了一个蛮有意思的人工智能学习网站,8个字形容一下"通俗易懂&#xff0c;风趣幽默"&#xff0c;感觉非常有意思,忍不住分享一下给大家。 &#x1f449;点击跳转到教程 前言&#xff1a; 今天在打开公司一个项目时&#xff0c;突然要重新下载相关的gradle&am…

Websocket实时音视频传输应用实战

背 景 随着互联网技术的发展&#xff0c;越来越多的企业和开发者开始寻求更高效、更稳定的通信解决方案。在这种背景下&#xff0c;WebSocket协议应运而生。WebSocket是一种在单个TCP连接上进行全双工通信的协议&#xff0c;它可以实现服务器和客户端之间的实时数据交换&#…

图像处理 mask掩膜

1&#xff0c;图像算术运算 图像的算术运算有很多种&#xff0c;比如两幅图像可以相加&#xff0c;相减&#xff0c;相乘&#xff0c;相除&#xff0c;位运算&#xff0c;平方根&#xff0c;对数&#xff0c;绝对值等&#xff1b;图像也可以放大&#xff0c;缩小&#xff0c;旋…

(二十一)从零开始搭建k8s集群——kubernates核心组件及功能介绍

前言 Kubernetes是一个可移植、可扩展、开源的平台&#xff0c;用于管理容器化的工作负载和服务&#xff0c;它促进了声明性配置和自动化。Kubernetes容器可以持续开发、集成和部署&#xff1a;可靠且频繁地构建和部署容器镜像&#xff0c;快速有效地回滚&#xff1b;开发与运…

点胶缺陷视觉检测都是怎么检测的?

点胶工艺是许多工业生产中不可或缺的一环&#xff0c;而点胶缺陷的存在往往直接影响到产品质量。为了提升点胶工艺的品质控制&#xff0c;点胶缺陷的视觉检测成为了一个重要的技术手段。 一、点胶缺陷的类型 点胶缺陷主要包括胶点大小不均、位置偏移、漏点、多点等。这些缺陷如…

IntelliJ IDEA 2020.2.4试用方法

打开idea&#xff0c;准备好ide-eval-resetter压缩包。 将准备好的压缩包拖入idea中 选中弹窗中的自动重置选项&#xff0c;并点击重置 查看免费试用时长

启动查看工具总结

启动目标&#xff1a;2s内优秀&#xff0c;2-5s普通&#xff0c;之后的都需要优化&#xff0c;热启动则是1.5s-2s内 1 看下大致串联启动流程&#xff1a; App 进程在 Fork 之后&#xff0c;需要首先执行 bindApplication Application 的环境创建好之后&#xff0c;就开始activ…

【Web前端】Vue核心基础

文章目录 1. Vue简介2. Vue官网使用指南3. 初识Vue3.1 搭建Vue开发环境3.2 HelloWorld案例3.3 el与data的两种写法3.4 MVVM模型3.5 模板语法 4. 数据绑定4.1 v-bind单向数据绑定4.2 v-model双向数据绑定 5. 事件处理5.1 v-on绑定事件5.2 事件修饰符5.3 键盘事件 6. 计算属性6.1…

typescript学习(更新中)

目录 开发环境搭建类型如何声明有哪些类型编译配置文件 开发环境搭建 npm i -g typescripttsc检查是否安装成功 类型如何声明 // 先声明再赋值 let a: number a 1// 直接赋值 let b 1function sum(a: number, b: number): number {return a b } console.log(sum(1, 2))有…

leetcode72. 编辑距离

leetcode72. 编辑距离 题目 思路 dp[i][j] 代表 word1 到 i 位置转换成 word2 到 j 位置需要最少步数&#xff0c;所以&#xff0c; 当 word1[i] word2[j]&#xff0c;dp[i][j] dp[i-1][j-1]&#xff1b; 当 word1[i] ! word2[j]&#xff0c;dp[i][j] 1 min(dp[i-1][j-1]…

Ubantu 18.04 如何映射IP到公网,外网可以访问

介绍一种简单的方式&#xff0c;就是通过路由侠 inux 系统安装路由侠&#xff0c;可通过两种方式进行&#xff0c;一种是通过直接脚本安装&#xff0c;一种是通过 Docker 安装。 windows下载地址&#xff1a;路由侠-局域网变公网 方式一&#xff1a;通过脚本安装 1、获取安…

java算法第十七天 | ● 110.平衡二叉树 ● 257. 二叉树的所有路径 ● 404.左叶子之和

110.平衡二叉树 leetcode链接 思路&#xff1a; 使用后序遍历分别求左右子树的高度&#xff0c;若高度只差大于一&#xff0c;则返回-1&#xff0c;否则返回当前节点的最大高度。 /*** Definition for a binary tree node.* public class TreeNode {* int val;* Tree…

【数据分享】2013-2022年全国范围逐日SO2栅格数据

空气质量数据是在我们日常研究中经常使用的数据&#xff01;之前我们给大家分享了2013-2022年全国范围逐月SO2栅格数据和逐年SO2栅格数据&#xff08;均可查看之前的文章获悉详情&#xff09;。 本次我们给大家带来的是2013-2022年全国范围的逐日的SO2栅格数据&#xff0c;原始…

阿里云几核服务器够用?内存多少合适?

阿里云服务器配置怎么选择&#xff1f;CPU内存、公网带宽和系统盘怎么选择&#xff1f;个人开发者或中小企业选择轻量应用服务器、ECS经济型e实例&#xff0c;企业用户选择ECS通用算力型u1云服务器、ECS计算型c7、通用型g7云服务器&#xff0c;阿里云服务器网aliyunfuwuqi.com整…

OJ_二叉排序树

题干 C实现 循环双指针法(一个指向父亲&#xff0c;一个指向待插入结点) #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <queue> using namespace std;struct TreeNode {char data;TreeNode* left;TreeNode* right; };void InsertBST(TreeNode* …

C# OpenCvSharp DNN FreeYOLO 人脸检测

目录 效果 模型信息 项目 代码 下载 C# OpenCvSharp DNN FreeYOLO 人脸检测 效果 模型信息 Inputs ------------------------- name&#xff1a;input tensor&#xff1a;Float[1, 3, 192, 320] --------------------------------------------------------------- Outp…