💓 在上一节我们手写了第一个chrome插件,手写第一个chrome插件!接下来我们来看 chrome插件零基础入门 专栏的第二篇文章,chrome常用语法汇总:
目录
2️⃣ storage用法
对数据进行存储,我们使用一个预算管理的例子来进行学习,我们每一次消费的时候,将以前消费的总金额和本次消费的金额进行相加,然后把总金额存储到浏览器当中,下一次我们进行消费的时候,同样将以前的金额取出,然后进行相加,再向浏览器中进行存储
🎈popup.html
<body style="width: 200px;height: 200px;">
<h2>总金额:<span id="total"></span></h2>
<h2>本次使用:<input type="text" id="amount"></h2>
<input type="submit" id="add" value="添加">
</body>
效果如图所示:
接下来进行逻辑的开发
现在manifest.json文件中加入storage的权限
"permission": [
"storage"
]
然后在popup.js文件中进行逻辑代码的编写
$(function(){
chrome.storage.sync.get('total',function(budget){
$('#total').text(budge.total);
});
$('#add').click(function(){
// 1. 从浏览器中获取存储的金额
// 第一个参数是获取数据的key,可以是一个也可以是两个
// 第二个参数是获取到数据之后的回调函数,参数是我们获取的对象
chrome.storage.sync.get('total',function(budget){
var totalAmount = 0;
if(budget.total){
totalAmount = parseFloat(budget.total);
}
// 2. 将本次金额加到总金额并存储
var amount = $('#amount').val();
if(amount){
totalAmount += parseFloat(amount);
chrome.storage.sync.set({'total':totalAmount});
}
// 3. 更新显示ui
$('#total').text(totalAmount);
$('#amount').val('');
});
})
})
3️⃣ options配置的用法
options主要用来设置插件的参数,比如上面storage里的预算管理的例子,我们可以首先对预算的使用金额的上限进行设置,当我们的消费金额达到该上限时,
首先在manifest里添加options_page的页面
"options_page": "options.html"
接下来我们来写options.html
<body>
<h1>预算管理选项</h1>
<h2>预算限制:<input type="text" id="limit"></h2>
<input type="submit" id="setLimit" value="保存限制">
<input type="submit" id="resetTotal" value="清除总金额">
</body>
之后写options.js文件
$(function(){
chrome.storage.sync.get('limit',function(budget){
$('#limit').val(budget.limit);
})
$('#setLimit').click(function(){
var limit = $('#limit').val();
if(limit){
// 这是个异步
chrome.storage.sync.set({'limit':limit},function(){
close();
})
}
});
$('#resetTotal').click(function(){
chrome.storage.sync.set({'total':0});
});
});
在popup.html文件中添加限制金额标签
<body style="width: 200px;height: 200px;">
<h2>总金额:<span id="total"></span></h2>
<h2>限制金额:<span id="limit"></span></h2>
<h2>本次使用:<input type="text" id="amount"></h2>
<input type="submit" id="add" value="添加">
</body>
在popup.js文件中添加限制金额
chrome.storage.sync.get('total','limit',function(budget){
$('#total').text(budge.total);
$('#total').text(budge.limit);
});
4️⃣ 消息通知 notifications
主要是用来实现通知,在电脑桌面的右小角位置出现弹框,来提示用户相关消息。接下来我们来实现当金额超过预算限制的时候弹出弹框实现通知
首先在manifest里对权限 permissions 进行添加
"permissions":[
"storage",
"notifications"
],
接下来接下来到 popup.js 文件中编写弹窗信息
首先把‘limit’传进去,来到options.js里,从浏览器获取存储的金额是,把 limit 传进来
// 1. 从浏览器中获取存储的金额,
// 把 limit 传进来
chrome.storage.sync.get('total','limit',function(budget){
var totalAmount = 0;
...
}
然后在存储金额的时候进行判断,如果总金额大于限额,弹出弹框
// 2. 将本次金额加到总金额并存储
var amount = $('#amount').val();
if(amount){
totalAmount += parseFloat(amount);
chrome.storage.sync.set({'total':totalAmount},function(){
// 在存储总金额的时候传入回调函数进行判断,
if(totalAmount > parseFloat(budget.limit)){
// 先设置弹窗的基本信息
var notifyOptions = {
// type 有四种类型,basic,image,simple,list
type: 'basic',
title: '金额超出限制',
iconUrl: 'img/logo.png',
message: '您消费的总金额已经超出上限'
}
// 接下来来生成弹窗, 传入两个参数,
// 第一个是弹窗的id,自己设置,第二个是刚才写好的弹窗内容
chrome.notifications.create('limitNofity',notifyOptions);
}
});
}
来查看下效果!
接下来我们来完善这个通知,当总金额清零的时候也能显示通知,
来到options.js文件中,当总金额为0时,弹出弹框,方式和上述相同
$('#resetTotal').click(function(){
chrome.storage.sync.set({'total':0},function(){
// 当 总金额为0的时候,设置弹窗
// 先设置弹窗的基本信息
var notifyOptions = {
// type 有四种类型,basic,image,simple,list
type: 'basic',
title: '提示',
iconUrl: 'img/logo.png',
message: '您的消费总金额已清零'
}
});
});
查看下效果:
5️⃣ contextMenus
contextMenus 也就是右键菜单,比如我们在某个商品购物页面,选中一个商品价格,点击鼠标右键,弹出选项卡,可以选择添加消费金额到总预算中,进行记账。这次我们进行操作的页面是普通的网页,不是之前做的插件的页面(popup.html,options.html),所以它的代码是运行在后台的,也就是 background,这和之前是不同的。接下来我们看下如何实现:
首先还是在manifest里,添加上 contextMenus 权限
"permissions":[
"storage",
"notifications",
"contextMenus"
],
然后对我们的后台进行一个声明,也就是 background ,background 需要设置两个属性,第一个是scripts:就是我们后台运行的js代码,写在这里;第二个属性 persistent ,这个属性是,在后台一直触发true,还是点击用到的时候才触发 false,这里我们设置 false
"background":{
"scripts": ["js/eventPage.js"],
"persistent": false
},
接下来我们来写 eventPage.js 文件
// 1. 创建contextMenus
// 1.1 先对右键菜单的属性进行一些设置
var contextMenu = {
id: "addAmount", // id 是唯一的标识
title: "添加消费",
// 触发情景,也就是什么情况下,菜单会显示
// selection 是指,选中文字点击右键才会触发
// 还有其他的选项,比如 page,点击页面触发;video 选中图片视音频会触发 等
contexts: ["selection"],
}
// 1.2 接着创建选项卡
chrome.contextMenus.create(contextMenu);
// 2. 为contextMenus 添加点击事件的监听
chrome.contextMenus.onClicked.addListener(function(clickData){
// clickData.menuItemId : 被点击的菜单选项卡id
// clickData.selectionText: 选中的内容、
// 先判断选项卡的id是否相符合,并且选择内容不为空,也就是有选择内容
if(clickData.menuItemId == "addAmount" && clickData.selectionText){
var amount = parseFloat(clickData.selectionText);
...
}
然后把存储金额的代码直接从 popup.js 文件里复制过来
if(clickData.menuItemId == "addAmount" && clickData.selectionText){
var amount = parseFloat(clickData.selectionText);
// 接下来将其添加到总金额中,这里就不写了直接将popup.js里写好的复制过来
chrome.storage.sync.get('total','limit',function(budget){
...
// 2. 将本次金额加到总金额并存储
// var amount = $('#amount').val();
// 这里注意,之前已经获取过了,不用在获取了
if(amount){
// 直接加上之前已经获取的amount就可以了
totalAmount += amount
// totalAmount += parseFloat(amount);
chrome.storage.sync.set({'total':totalAmount},function(){
...
});
}
});
效果图就不展示了。
6️⃣ badge 徽章
badge 徽章 就是显示在浏览器右上角,插件位置上的内容。我们现在想实现的功能呢,就是每次存储了的总金额显示在插件上,比如下图,这个蓝色的数字729。
直接在eventPage.js 里添加一个监听事件,当总金额发生改变时,就显示badge
// 传入两个参数,一个是 changes,是改变的值,一个是storageName,存储的名称
chrome.storage.onChanged.addListener(function(changes,storageName){
// 第一步先取出total值,total里还包括两个值,一个是变化前的值,一个是变化后的值
// changes.total.newValue : 总金额变化后的值
// 设置badge显示的文字, 注意,传入显示的内容的时候,要把它转成字符串
chrome.browserAction.setBadgeText({"text": changes.total.newValue.toString()});
// 也可以对badge的背景色进行修改
chrome.browserAction.setBadgeBackgroundColor({"color":[0,255,0,255]});
})
注意,由于位置有限,badge上只能显示前四个字符,后面的会自动省略
7️⃣ pageAction
pageAction是针对页面有用的,而browserAction是针对浏览器的,对所有页面都有用,比如我们仔细观察插件就会发现,有的插件图标在浏览器的所有页面都是彩色的,有的插件图标只在特定的页面才是彩色的,这是 pageAction 和 browserAction 两种插件,我们今天学习的 pageAction 是在特定的页面才是彩色的可用的,在其他页面是灰色的,是不可用的
第一步还是先编写manifest,需要将 browserAction 改写成 pageAction,default_title:当鼠标悬停在插件上的时候,显示文字。
"page_Action": {
"default_icon": "img/logo.png",
"default_title": "page Action 插件",
"default_popup": "popup.html"
},
这样我们在写个简单的popup.html,这里就不具体写了,然后加载了这个插件,可以看出,插件图标是灰色的。
点击插件图标,插件才会运行,我们需要把运行的代码写在 background 里,
"background":{
"scripts": ["js/pageAction.js"],
"persistent": false
},
接着我们来写 pageAction 页面,先来简单写一下,比如指定页面,让我们的插件在淘宝页面可用,也就是在淘宝页面插件图标是彩色的。
// 查询浏览器的标签,传入的参数,首先是当前页面允许使用插件,
// 然后传入允许的 url,这里比如下淘宝页面,
// 然后把查询的结果,tabs传入一个回调函数,引入今来
chrome.tabs.query({currentWindow:true, url: "https://www.taobao.com/"},function(tabs){
// show里传入的是浏览器的id,这里tabs只有一个
chrome.pageAction.show(tabs[0].id);
})
注意,我们这里使用了tabs,需要在 manifest 引入
"permissions":[
"tabs",
],
这样就算完成了,试一下就好了。
8️⃣ chrome_url_overrides
这一小节主要讲浏览器某些页面的复写、重写,也就是说我们可以自定义浏览器的的某些页面,可以自定的页面主要有3个:1. 新的标签页,当我们点击+号打开的新的标签页;2.历史记录页面; 3. 书签管理页面;现在我们自定也这3个页面,把他们替换成我们想要写的页面。比如,当我们每次打开新的标签页时,都会在新的标签页显示淘宝主页,下面我们来实现该功能:
首先还是来写 manifest 文件,我们需要定义一个"chrome_url_override",第一个参数是需要重写的是哪个页面,newtab表示新的标签页,代表我们要重写的是新的标签页。
{
"manifest_version": 2,
"name": "helloWorld",
"version": "1.0",
"description": "重写页面",
"icons":{
"128": "img/logo.png",
"48": "img/logo.png",
"16": "img/logo.png"
},
"chrome_url_overrides": {
"newtab":"new.html"
}
}
然后我们创建一个 new.html 页面
<html>
<head>
<meta charset="utf-8">
<title>淘宝</title>
</head>
<body>
<h1>淘宝</h1>
<h2><a href="https://www.taobao.com/"></a></h2>
</body>
</html>
这样就写好了,如果想改写历史记录页面,将 newtab 替换成 history,书签页是 bookmarks,注意,这三个页面,每次只能改写其中一个。
9️⃣ content_scripts
🎈content_scripts
content_scripts 是在 web 页面内运行的 JavaScript 脚本,通过使用标准的 DOM,他们可以获取浏览器所访问页面的详细信息,并且可以修改这些信息。 content_scripts 不仅可以注入js脚本,也可以注入css脚本,也可以使用jQuery来获取我们的 DOM。
所以 content_scripts 可以获取 DOM 元素、 修改 DOM 元素、修改样式;
同时 content_scripts 不能使用除了 chrome.extension 之外的 chrome.* 的接口、不能访问它所在扩展中定义的函数和变量,比如background里的、不能访问 web 页面或其它 content_scripts 中定义的函数和变量、不能做 cross-site XMLHttpRequests,也就是不能跨站。
看了这些不能做的,好像觉得 content_scripts 都不能做了,但其实也是有解决方案的:
1. content_scripts 可以使用 messages 机制与它所在的扩展通信,来间接使用 chrome.* 接口,或访问扩展数据。
2. content_scripts 还可以通过共享的 DOM 来与 web页面通信。
首先需要在manifest里面声明我们的 content_scripts , content_scripts 是个数组,里面有对象,matches标明我们的代码向哪些页面里面注入,这次我们以百度为例,这里用个匹配的*,所有的百度页面都能用,js是引入的js代码,
"content_scripts": [
{
"matches": ["https://*.baidu.com/"]
"js": ["js/juery-3.3.1.min.js","js/content.js"]
}
]
同时需要在 permissions 里引入百度url
"permissions":[
"tabs",
"https://*.baidu.com/"
],
这时,我们打开百度相关的页面,然后点击插件图标,显示的就是content.js的代码,下面我们来写 content.js页面
我们来通过content.js 页面向 background 发送消息
// 传入个对象,发送消息,然后到 pageAction页面来接收
chrome.runtime.sendMessage({todo:"showPageAction"})
然后我们来到 pageAction 页面接收消息
// 来接收content.js页面发来的消息,
// 这里的回调函数传入了三个参数
// 第一个request 传过来的一些信息
chrome.runtime.onMessage.addListener(function(request,sender,response){
// 在这里onMessage里面,我们会收到所有来自conten.js页面发来的消息,
// 所以我们需要先判断一下,
if(request.todo == "showPageAction"){
// 这样就找到了对应的消息了
// 先找到当前的标签,active表示激活状态,currentWindow表示当前页面
chrome.tabs.query({active:true,currentWindow:true},function(tabs){
// 找到之后,引入一个回调函数,回调函数的参数是找到的标签tabs
// 之后让我们的页面显示
chrome.pageAction.show(tabs[0].id);
})
}
})
这样就ok了,我们只有打开百度相关页面的时候,插件图标才是彩色的,并且点击图标会显示相关消息。
我们再来重新捋一下逻辑,现在 manifest 文件引入 content_scripts,并且设置打开百度相关网页后,在此网页注入 js 代码(比如content.js)然后在 content.js 页面书写向背景页 pageAction.js 发送的消息,pageAction 收到消息后,就会通过pageAction.show 将消息显示出去。
🎈 executeScript
上面我们学了 content_scripts 是个向页面注入代码的方法,这一小节,我们来看一种更便捷的向页面注入代码的方法 executeScript。
之前使用 content_scripts 时,是直接在manifest.json文件中用 content_Scripts 注入JavaScript 或css文件到页面中,这个方法有几个弊端:
1. 文件直接卸载了manifest中,灵活性差;
2. 即使只执行1行代码也要注入一个文件
3. 执行的时机不好控制
这些问题在用 executeScript 的方法就可以解决了。
下面我们来用 executeScript 实现个小需求:当我们查看网页时觉得字体太小了,右击页面,弹出菜单中点击增大字体,可以增大网页字体字号了。
首先来写manifest,其中需要在 permissions 里添加 <all_urls> 表示所有页面均有效
"background": {
"scripts":["js/increase.js"],
"persistent": false
},
"permissions": [
"contextMenus",
"tabs",
"<all_urls>"
]
}
接下来我们来写 increase.js
var menuItem = {
"id": "increase",
"title": "增大字体",
"contexts": ["all"]
// 所有,都适用
};
chrome.contextMenus.create(menuItem);
chrome.contextMenus.onClicked.addListener(function(clickData){
// executeScript 是在tabs里面的
// 第一个参数就是tabs的id,我们使用null,
// 第二个参数是code,表示执行的代码
chrome.tabs.executeScript(null,{code:"var old = window.getComputedStyle(document.body).fontSize;\
var index = old.indexOf('p');\
var size = parseInt(old.substring(0,index));\
var newSize = size + 10 + 'px;\
document.body.style.fontSize = newSize;"})
})
/**
* 将下面这段代码引入,code里
*/
// 获取网页字体大小
// 由于获取到的字体是个字符串,没法直接加,old="18px"所以
// var old = window.getComputedStyle(document.body).fontSize;
// var index = old.indexOf('p');
// var size = parseInt(old.substring(0,index));
// var newSize = size + 10 + 'px';
// document.body.style.fontSize = newSize;
这样就完成啦!
🎈web_accessiblet:resources
向页面中插入文件 web_accessiblet:resources ,上面我们学过向网页中插入 JavaScript 和css ,但是如果想要插入的是图片或其他类型的文件,我们可以在 web_accessiblet:resources 中进行声明,下面我们来通过 web_accessiblet:resources 实现一个需求:我们需要将页面的背景图设置成一张好看的图。
首先需要在manifest 中声明引入的图片
"web_accessiblet:resources": [
"img/*"
]
然后来到js文件里写入代码、
var menuItem = {
"id": "increase",
"title": "设置背景图",
"contexts": ["all"]
// 所有,都适用
};
chrome.contextMenus.create(menuItem);
chrome.contextMenus.onClicked.addListener(function(clickData){
// 首先要得到图片的url
var imgUrl = chrome.extension.getURL("img/love.jpg");
chrome.tabs.executeScript(null,{code:"\
document.body.style.backgroundImage = 'url(\""+imgUrl+"\")';\
document.body.style.backgroundRepeat = 'repeat';"});
})
这样就完成啦!不演示啦!很简单!
🎈 insertCSS
这是content_scripts 的最后一块了,
修改页面样式insertCSS 和 executeScript 用法相同,只是 insertCSS 执行css 代码或文件,而 executeScript 执行 js 代码或文件,现在我们还是来实现个小需求:将页面搜索结果块的背景设置成绿色。
首先在 manifest 里的 "web_accessiblet:resources" 删除,然后来到 js 文件
var menuItem = {
"id": "increase",
"title": "设置背景颜色",
"contexts": ["all"]
// 所有,都适用
};
chrome.contextMenus.create(menuItem);
chrome.contextMenus.onClicked.addListener(function(clickData){
// 之前我们演示的时候,一直用的是code,这次就用file来演示吧
chrome.tabs.insertCSS(null,{file:"backColor.css"})
})
然后我们的css代码写在 backColor.css 文件里就可以啦
🔟 connect 长连接消息对话
这一小节我们来介绍3种消息传递方式并对其中的长消息传递进行详细了解。
消息传递的3种方式:
1. 一次性消息传递,这个上面讲了;2.长连接消息;3.插件间的消息传递,这种用的比较少,就不介绍了
长连接消息传递使用的是connect,消息发送之后,会等待消息的回复,使对话一直持续下去。
下面我们来实现一个简单的需求:在 content_scripts 和 background 之间进行一次长消息对话。
我们找到之前写一次性消息传递的案例的文件代码,在此基础上进行修改,可以对照着这两小节进行学习,manifest 只需要求改一些 name、title之类的,就可以了,就不展示代码了。下面来到 js 文件。
首先在 content.js 文件
// 传入个对象,发送消息,然后到 pageAction页面来接收
chrome.runtime.sendMessage({todo:"showPageAction"})
// 用port表示建立的连接
var port = chrome.extension.connect({name:"knock"});
// 用port 来发送消息
port.postMessage({question:"你好有人吗?"});
// 然后进行消息监听
port.onMessage.addListener(function(msg){
if(msg.answer == "有人呀!"){
port.postMessage({question: "那你是谁呢?"})
}else if(msg.answer == "我是咯咯咯"){
port.postMessage({question: "有你的快递"})
}
})
background.js
chrome.extenstion.onConnect.addListener(function(port){ // 这是对我们的连接进行监听
// 之后对消息进行监听
port.onMessage.addListener(function(msg){
if(msg.question == "你好有人吗?" ){
port.postMessage({answer:"有人呀!"})
}else if(msg.question == "那你是谁呢?"){
port.postMessage({answer:"我是咯咯咯"});
}
})
})
这两个文件需要对应着来书写,仔细看下代码逻辑就能理解了。
💓 至此,chrome基本的常用语法就学完了,下一节我们来通过一个百度翻译的案例综合使用下chrome语法!