简单功能:点击浏览器右上角插件icon弹出小弹窗,点击设置弹出设置页,并替换背景颜色。
{
"name": "testPlugin",
"description": "这是一个测试用例",
"version": "0.0.1",
"manifest_version": 2
}
{
"name": "testPlugin",
"description": "这是一个测试用例",
"version": "0.0.1",
"manifest_version": 2,
"icons": {
"16": "icons/16.png",
"48": "icons/16.png"
}
}
这时候在扩展程序中加载已解压的程序(就是我们创建的文件夹),就可以看到雏形了:
"browser_action": {
"default_title": "test plugin",
"default_icon": "icons/16.png",
"default_popup": "index.html"
}
testPlugin创建index.html文件:
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>test plugintitle>
head>
<body>
<input id="name" placeholder="请输入"/>
body>
html>
刷新插件,这时候点击浏览器中刚刚添加的插件的icon,就会弹出:
document.getElementById('button').onclick = function() {
alert(document.getElementById('name').value)
}
html中:
<input id="name" placeholder="请输入"/>
<input id="button" type="button" value="点击"/>
<script src="js/index.js">script>
刷新插件,这时候点击浏览器中刚刚添加的插件的icon,就会弹出输入框中的值:
上述例子是点击icon浏览器右上角出现的小弹窗,
"content_scripts": [
{
"matches": [
""
],
"css": [
"css/index.css"
],
"js": [
"js/vue.js",
"js/element.js",
"js/index.js"
],
"run_at": "document_idle"
}
],
在index.js文件:
这里使用在head里插入link 的方式引入element-ui的css,减少插件包的一点大小,当然也可以像引入index.js那样在manifest.json中引入。
直接在index.js文件中写Vue实例,不过首先得创建挂载实例的节点:
let element = document.createElement('div')
let attr = document.createAttribute('id')
attr.value = 'appPlugin'
element.setAttributeNode(attr)
document.getElementsByTagName('body')[0].appendChild(element)
let link = document.createElement('link')
let linkAttr = document.createAttribute('rel')
linkAttr.value = 'stylesheet'
let linkHref = document.createAttribute('href')
linkHref.value = 'https://unpkg.com/element-ui/lib/theme-chalk/index.css'
link.setAttributeNode(linkAttr)
link.setAttributeNode(linkHref)
document.getElementsByTagName('head')[0].appendChild(link)
const vue = new Vue({
el: '#appPlugin',
template:`
{
{text}}{
{icon_post_message}}Button
`,
data: function () {
return {
text: 'hhhhhh', icon_post_message: '_icon_post_message', isOcContentPopShow: true }
},
mounted() {
console.log(this.text)
},
methods: {
Button() {
this.isOcContentPopShow = false
}
}
})
index.js:
let element = document.createElement('div')
let attr = document.createAttribute('id')
attr.value = 'appPlugin'
element.setAttributeNode(attr)
document.getElementsByTagName('body')[0].appendChild(element)
let link = document.createElement('link')
let linkAttr = document.createAttribute('rel')
linkAttr.value = 'stylesheet'
let linkHref = document.createAttribute('href')
linkHref.value = 'https://unpkg.com/element-ui/lib/theme-chalk/index.css'
link.setAttributeNode(linkAttr)
link.setAttributeNode(linkHref)
document.getElementsByTagName('head')[0].appendChild(link)
const vue = new Vue({
el: '#appPlugin',
template: `
颜色
背景:
字体:
`,
data: function () {
return {
color1: null, color2: null, documentArr: [], textArr: [], isOcContentPopShow: true }
},
watch: {
color1(val) {
let out = document.getElementById('oc_content_page')
let outC = document.getElementsByClassName('el-color-picker__panel')
this.documentArr.forEach(item => {
if(!out.contains(item) && !outC[0].contains(item) && !outC[1].contains(item)) {
item.style.cssText = `background-color: ${
val}!important;color: ${
this.color2}!important;`
}
})
},
color2(val) {
let out = document.getElementById('oc_content_page')
let outC = document.getElementsByClassName('el-color-picker__panel')[1]
this.textArr.forEach(item => {
if(!out.contains(item) && !outC.contains(item)) {
item.style.cssText = `color: ${
val}!important;`
}
})
}
},
mounted() {
chrome.runtime.onConnect.addListener((res) => {
if (res.name === 'testPlugin') {
res.onMessage.addListener(mess => {
this.isOcContentPopShow = mess.isShow
})
}
})
this.$nextTick(() => {
let bodys = [...document.getElementsByTagName('body')]
let headers = [...document.getElementsByTagName('header')]
let divs = [...document.getElementsByTagName('div')]
let lis = [...document.getElementsByTagName('li')]
let articles = [...document.getElementsByTagName('article')]
let asides = [...document.getElementsByTagName('aside')]
let footers = [...document.getElementsByTagName('footer')]
let navs = [...document.getElementsByTagName('nav')]
this.documentArr = bodys.concat(headers, divs, lis, articles, asides, footers, navs)
let as = [...document.getElementsByTagName('a')]
let ps = [...document.getElementsByTagName('p')]
this.textArr = as.concat(ps)
})
},
methods: {
close() {
this.isOcContentPopShow = false
}
}
})
index.html:
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>my plugintitle>
<link rel="stylesheet" href="css/index.css">
head>
<body>
<div class="plugin">
<input id="plugin_button" type="button" value="打开" />
div>
body>
<script src="js/icon.js">script>
html>
新建icon.js:
plugin_button.onclick = function () {
mess()
}
async function mess () {
const tabId = await getCurrentTabId()
const connect = chrome.tabs.connect(tabId, {
name: 'testPlugin'});
connect.postMessage({
isShow: true})
}
function getCurrentTabId() {
return new Promise((resolve, reject) => {
chrome.tabs.query({
active: true, currentWindow: true }, function (tabs) {
resolve(tabs.length ? tabs[0].id : null)
});
})
}
新建index.css:
.oc-move-page{
width: 100px;
height: 200px;
background: white;
box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.12);
border-radius: 8px;
position: fixed;
transform: translateY(-50%);
right: 0;
top: 50%;
z-index: 1000001;
}
.oc-move-page .oc-content-title{
text-align: left;
padding: 12px 16px;
font-weight: 600;
font-size: 18px;
border-bottom: 1px solid #DEE0E3;
}
.oc-move-page .app-plugin-content {
display: flex;
align-items: center;
margin-top: 10px;
}
.el-color-picker__panel {
right: 100px!important;
left: auto!important;
}
这样一个小尝试就完成了,当然如果有更多需求可以结合本地存储或者服务端来协作。