全方面手把手从0到1带你开发谷歌浏览器插件

35 篇文章 12 订阅
30 篇文章 1 订阅

谷歌浏览器开发

一、创建myPlugin文件夹以及manifest.json文件

1、在manifest.json文件写入这段代码

如果你对manifest.json里面的字段描述不清楚,建议先看完此文章,先照猫画虎,在阅读 manifest.json 字段解析文章 网上最全谷歌浏览器插件manifest.json文件字段解析

{
    "name": "my Plugin",
    "description": "this is my plugin",
    "version": "0.0.1",
    "manifest_version": 2
}
2、在谷歌浏览器中打开管理扩展程序
1. 如图打开

2. 或者在浏览器中输入chrome://extensions 打开拓展程序
3、加载已解压的拓展程序

在这里插入图片描述

然后选择到你的 myPlugin 文件夹确定即可

就会在扩展程序中看到你的插件了

在这里插入图片描述

在这边的插件信息中可以看到在你的 manifest.json 中的namedescriptionversion

此时点击右上角插件icon如下展示

在这里插入图片描述

如果你的插件icon没有展示出来,可以进行如下操作,把它固定在右上角

在这里插入图片描述

4、到此一个简单的插件完成了,剩下的就是往里面添加东西了

二、添加点击插件的弹出页面

例如谷歌翻译插件点击之后会有一个弹出页面

在这里插入图片描述

1、添加东西之前首先把自己插件的icon加一下
  1. 创建一个icons文件夹
  2. 找三张图片尺寸 16 * 16、48 * 48、128 * 128
  3. 添加到 manifest.json 文件中
"icons": {
    "16": "icons/icon16.png",
    "48": "icons/icon48.png",
    "128": "icons/icon128.png"
}

在扩展程序中刷新下我们的插件(我这边选的图片是网上找的chrome图标)

在这里插入图片描述

此时浏览器右上角icon也换成了我们的图片,只是此时是灰色的

在这里插入图片描述

2、添加 browser_action
  1. myPlugin文件夹中创建index.html文件,内容如下
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>my plugin</title>
</head>
<body>
    this is my plugin 
    browser_action html
</body>
</html>
  1. manifest.json中添加browser_action字段
"browser_action": {
    "default_title": "plugin title",
    "default_icon": "icons/icon128.png",
    "default_popup": "index.html"
}
  1. 拓展程序中刷新插件
  2. 点击右上角插件icon

3、此时一个插件弹出页面就出来了

三、仿着谷歌翻译插件的弹出页面修改

此时就相当于web页面开发,需要引入cssjs

  1. myPlugin文件夹下创建 css文件夹和jswen jian j文件夹
  2. css中创建index.css,并在index.html中引入
  3. js中创建index.js,并在index.html中引入
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>my plugin</title>
    <link rel="stylesheet" href="css/index.css">
</head>
<body>
    <div class="plugin_search">
        <div class="plugin_search_bar">
            <input id="plugin_search_inp" />
            <input id="plugin_search_but" type="button" value="翻译" />
        </div>
        <div class="plugin_span">
            <span>翻译此页面</span>
        </div>
    </div>
    
    <div class="plugin_footer">
        <span>© 2015 Google -</span>
        <a target="_blank" href="https://google.com/">扩展程序选项</a>
        <a target="_blank" href="https://translate.google.com/?source=gtx">Google 翻译</a>
    </div>
</body>
<script src="js/index.js"></script>
</html>
*{
    padding: 0;
    margin: 0;
    list-style: none;
    text-decoration: none;
}
.plugin_search{
    margin: 15px 30px 15px 30px;
}
.plugin_search_bar{
    margin: 8px 0 16px 0;
}
#plugin_search_inp{
    font-size: 14px;
    margin: 2px;
    height: 23px;
    width: 70%;
}
#plugin_search_but{
    box-shadow: none;
    background-color: #4d90fe;
    background-image: -webkit-linear-gradient(top,#4d90fe,#4787ed);
    border: 1px solid #3079ed;
    color: #fff;
    border-radius: 2px;
    cursor: default;
    font-size: 11px;
    font-weight: bold;
    text-align: center;
    white-space: nowrap;
    margin-right: 16px;
    height: 27px;
    line-height: 27px;
    width: 54px;
    outline: 0px;
    padding: 0 8px;
    box-sizing: content-box;
}
.plugin_span{
    color: #4285f4;
}
.plugin_footer{
    background-color: #f0f0f0;
    color: #636363;
    font-family: 'Roboto',sans-serif;
    font-size: 11px;
    margin-top: 9px;
    padding: 10px;
    text-align: center;
    width: 400px;
}
.plugin_footer a{
    color: #4285f4;
}
const plugin_search_but = document.getElementById('plugin_search_but')
const plugin_search_inp = document.getElementById('plugin_search_inp')
plugin_search_but.onclick = function () {
    alert('plugin_search_inp的值为:' + plugin_search_inp.value.trim())
}
  1. 扩展程序中刷新
  2. 点击右上角插件icon
  3. 在输入框中输入文案,并点击按钮

在这里插入图片描述

  1. 如果想有其他操作和样式,直接在jscss文件中写入即可

四、background

如果我在 index.js 中添加如下一段js

setInterval(() => {
    alert('alert')
}, 5000);

每隔五秒 alert 一下

当我刷新插件后,点击icon,每隔五秒就会 弹出一次,但是当我把 弹出框 取消掉之后,发现就不会在弹了,只有再次打开才会每隔五秒执行一次。

这个可以满足一些插件需求,只要当我点击插件的时候,才会执行插件的某些操作,不点击的话不会执行,但是某些需求是,不点击的时候也要执行我插件的某些操作

这个时候就需要 background来实现了

  1. myPlugin中 建一个background.js的文件
  2. background.js的文件添加如下代码
setInterval(() => {
    alert('background')
}, 5000);
  1. 然后在manifest.json中把background.js加入进来
"background": {
    "scripts": ["background.js"]
}

如果你需要在background中添加多个js,只需要在scripts数组中按照顺序添加,先后顺序影响着加载顺序

此时会发现,不需要点击icon就会每隔五秒弹出一个弹框

此时你的插件就可以在 点击 插件icon进行你插件的需求,和不点击运行你的插件需求(后台运行你的插件需求)

五、content_scripts 能够操作当前页面(domdocumentwindowlocation…)

不知道你有没有发现,如果你在index.js/background.jsconsole.log(document)/window都和你当前打开的网页无关…一个是你的插件页面,一个是你的背景页面

而此时,产品站在你旁边,碎碎念,我想通过插件操作当前页面dom的需求,那这个时候index.jsbackground.js就不行了。

此时就需要 content_scripts

先把 background.jsalert 注释掉,在刷新下插件(一直弹,挺烦)

  1. myPlugin文件夹中新建一个 contentJs 文件夹
  2. contentJs中新建一个index.js文件,在从网上找一个jquery.js文件,需要用到(Jquery)
  3. manifest.json文件中把content_scripts引入进来
"content_scripts": [
    {
        "matches": ["https://*.taobao.com/*"],
        "js": ["contentJs/jquery.js", "contentJs/index.js"],
        "run_at": "document_idle"
    }
]
  • matches:意思是要在哪些页面引入这些js
  • js:要引入的js,按照数组顺序加载
  • run_at:js引入的运行时间

在上面的代码中,我想注入的是 https://*.taobao.com/*这个淘宝域名下的页面

  1. index.js 里面输入下面一段代码
console.log("this is index.js")
console.log(document)
console.log(location)
  1. 刷新插件,打开https://www.taobao.com/,打开控制台

在这里插入图片描述

此时你代码里面的 console.log 的内容就出现在控制台中,就可以操作当前页面了

六、在当前页面中加入我的 html 代码

此时产品看到你可以操作当前页面了,又来需求了。

在当前页面加入一个dialog框,可以操作XXXXXXX,我还想在当前页面表格的每一行里面加一个按钮XXXX…等

通过 content_scripts 我们可以正常操作页面,那加一个弹框,那就是htmlcss

  1. myPlugin中创建contentCss文件夹,里面创建index.css文件
  2. manifest.json中引入
"content_scripts": [
    {
        "matches": ["https://*.taobao.com/*"],
        "css": ["contentCss/index.css"],
        "js": ["contentJs/jquery.js", "contentJs/index.js"],
        "run_at": "document_idle"
    }
]

css引入

index.css内容

#cj_move_page{
    width: 400px; 
    user-select: none; 
    background: white; 
    border: 1px solid; 
    height: 400px; 
    position: fixed; 
    right: 0; 
    bottom: 0; 
    z-index: 1000001;
}
#cj_move_h3{
    text-align: center; 
    line-height: 40px; 
    cursor: move;
}

contentJs/index.js文件内容

console.log("this is index.js")
console.log(document)
console.log(location)

//创建页面函数
function createPage () {
    const page = $('<div id="cj_move_page"></div>')
    const h3 = $('<h3 id="cj_move_h3">my Plugin</h3>')
    page.append(h3)
    $('body').append(page)
    //拖拽
    drag(cj_move_h3)
}
createPage()

//拖拽
function drag(ele) {
    let oldX, oldY, newX, newY
    ele.onmousedown = function (e) {
        if (!cj_move_page.style.right && !cj_move_page.style.bottom) {
            cj_move_page.style.right = 0
            cj_move_page.style.bottom = 0
        }
        oldX = e.clientX
        oldY = e.clientY
        document.onmousemove = function (e) {
            newX = e.clientX
            newY = e.clientY
            cj_move_page.style.right = parseInt(cj_move_page.style.right) - newX + oldX + 'px'
            cj_move_page.style.bottom = parseInt(cj_move_page.style.bottom) - newY + oldY + 'px'
            oldX = newX
            oldY = newY
        }
        document.onmouseup = function () {
            document.onmousemove = null
            document.onmouseup = null
        }
    }
}

js中创建页面,并加载到页面的body

  1. 刷新插件
  2. 刷新淘宝页面

在这里插入图片描述

此时就可以在content_scriptsmatches所匹配的页面里面插入你所写的dom元素了

七、ajax请求

页面当然离不开 ajax 请求了

1、content_scriptsajax请求

由于我们之前在content_scripts中引入了jquery,那我们就可以直接用$.ajax

  1. 首先我们先在manifest.json中在添加一个域名:豆瓣(www.douban.com)
"content_scripts": [
    {
        "matches": ["https://*.taobao.com/*", "https://*.douban.com/*"],
        "css": ["contentCss/index.css"],
        "js": ["contentJs/jquery.js", "contentJs/index.js"],
        "run_at": "document_idle"
    }
]
  1. 在我们的contentJs/index.js中加入一个button
function createPage() {
    const page = $('<div id="cj_move_page"></div>')
    const h3 = $('<h3 id="cj_move_h3">my Plugin</h3>')
    const but1 = $('<button id="cj_but1">加载更多</button>')
    page.append(h3)
    page.append(but1)
    $('body').append(page)
    $('#cj_but1').click(function (e) {
        $.ajax({
            url: "https://www.douban.com/j/search",
            type: "GET",
            data: {
                q: '电影',
                start: 10,
                cat: 1002,
            },
            success: function (res) {
                console.log(res)
            },
            error: function (e) {
                console.log(e.responseText)
            }
        })
    })
    //拖拽
    drag(cj_move_h3)
}
  1. 刷新插件、刷新豆瓣页面

在这里插入图片描述

  1. 点击加载更多

在这里插入图片描述

2、background调用ajax
  1. 首先先把jquery.js引入
"background": {
    "scripts": ["contentJs/jquery.js", "background.js"]
},

注意顺序

background.js页面

$.ajax({
    url: "https://www.douban.com/j/search",
    type: "GET",
    data: {
        q: '电影',
        start: 10,
        cat: 1002,
    },
    success: function (res) {
        console.log(res)
    },
    error: function (e) {
        console.log(e.responseText)
    }
})
  1. 刷新插件
  2. 点击插件背景页按钮

在这里插入图片描述

  1. 点击 consoleajax请求内容如下

在这里插入图片描述

3、插件弹出页面调用ajax

插件弹出页面调用ajax,这个就不用再说了,就和普通页面一样,引入jquery,然后在js页面直接调用即可

八、js之间的消息通讯

现在有我们有content_scriptsbackground scripts和弹出框页面的scripts

可能需要js之间的消息通信

1、content_scriptsbackground的通信
  • 接收消息:chrome.runtime.onMessage.addListener
  • 发送消息:chrome.runtime.sendMessage
  1. 我们先在content_scripts里面加一个按钮,用来触发事件

contentJs/index.js

//contentJs/index.js
const but2 = $('<button id="cj_but2">向background发送消息</button>')
// 添加一个 button 按钮
page.append(but2)
$('body').append(page)
// 点击事件
$('#cj_but2').click(function (e) {
    // 点击按钮发送消息
    chrome.runtime.sendMessage({
        info: "我是 content.js, 我在发送消息"
    }, res => {
        console.log('我是 content.js ,我收到消息:', res)
    })
})
// 接收消息
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
    console.log(request, sender, sendResponse)
    sendResponse('我收到了你的消息!');
});
  1. background.js页面接收和发送消息

background.js

//background.js
//接收消息
chrome.runtime.onMessage.addListener(async (req, sender, sendResponse) => {
    console.log('我是background,我接收了来自 content.js的消息:', req.info)
    sendResponse('哈哈哈')
    const tabId = await getCurrentTabId()
    // 在背景页面发送消息,需要当前 tabID
    chrome.tabs.sendMessage(tabId, '我是background,我在发送消息', function (res) {
        console.log('background:', res)
    });
})
/**
 * 获取当前 tab ID
 */
function getCurrentTabId() {
    return new Promise((resolve, reject) => {
        chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
            resolve(tabs.length ? tabs[0].id : null)
        });
    })
}
  1. 刷新插件、刷新页面

此时是有一个 button 按钮

在这里插入图片描述

  1. 点击按钮,触发事件

  2. 在 页面的控制台中输出的信息

在这里插入图片描述

  1. 在背景页的控制台中输出的信息

在这里插入图片描述

2、background.js右上角弹出框的通信
  • 在background中: chrome.extension.getViews() 获取当前插件内每个运行页面的窗口数组([window, window])
  • 在右上角弹出框中:chrome.extension.getBackgroundPage() 获取背景页面的窗口对象(window)
  1. background.js中加入下面一段代码
//background.js
/**
 * 通信函数
 */
function backFun () {
    console.log('arguments:', arguments)
    const allViews = chrome.extension.getViews()
    console.log('chrome.extension.getViews():', allViews)
}
  1. index.js中把我们之前的定时器注释掉,alert影响流程,然后把按钮点击事件改一下,获取background页面的window对象,并调用
// index.js
const background = chrome.extension.getBackgroundPage();
console.log(background)
plugin_search_but.onclick = function () {
    // alert('plugin_search_inp的值为:' + plugin_search_inp.value.trim())
    background.backFun('这个是参数1', '这个是参数2')
}
  1. 刷新插件
  2. 点击右上角 icon
  3. 右键查看元素,打开弹出页面的控制台**和背景页面的控制台不是一个**
  4. 点击按钮

在插件控制台显示如下

在背景页面的控制台显示

在这里插入图片描述

显示一个函数调用 console值 和一个 window 对象数组

3、右上角弹出框content_scripts之间的通信
  • 右上角弹出框:chrome.tabs.connect,链接content_scripts的脚本通信
  • content_scripts:chrome.runtime.onConnect
  1. 先在content_scripts添加chrome.runtime.onConnect用了监听链接:

contentJs/index.js

// `contentJs/index.js`
chrome.runtime.onConnect.addListener((res) => {
    console.log('contentjs中的 chrome.runtime.onConnect:',res)
    if (res.name === 'myConnect') {
        res.onMessage.addListener(mess => {
            console.log('contentjs中的 res.onMessage.addListener:', mess)
            res.postMessage('哈哈哈,我是contentjs')
        })
    }
})
  1. 再在右上角弹出框index.js中建立链接:

index.js

把我们的按钮事件改掉,改成我们的消息触发事件

// index.js
plugin_search_but.onclick = function () {
    // alert('plugin_search_inp的值为:' + plugin_search_inp.value.trim())
    // background.backFun('这个是参数1', '这个是参数2')
    mess()
}
async function mess () {
    const tabId = await getCurrentTabId()
    const connect = chrome.tabs.connect(tabId, {name: 'myConnect'});
    console.log(connect)
    connect.postMessage('这里是弹出框页面,你是谁?')
    connect.onMessage.addListener((mess) => {
        console.log(mess)
    })
}

/**
 * 获取当前 tab ID
 */
function getCurrentTabId() {
    return new Promise((resolve, reject) => {
        chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
            resolve(tabs.length ? tabs[0].id : null)
        });
    })
}
  1. 刷新插件
  2. 点击插件右上角icon
  3. 在插件弹出框中右键打开控制台
  4. 点击按钮执行操作

插件弹出框控制台显示:

在这里插入图片描述

页面中的控制台显示:

在这里插入图片描述

此时有人想问了,这个是右上角弹出框向content_scripts通信,那content_scripts向右上角弹出框通信呢?

弹出框只要点击插件才能弹出,而当你操作页面的时候,插件弹框又会消失…消失之后,弹框的.js等都会销毁…所以,可以向background通信,然后点击弹出之后,弹出框和background通信,或者弹出之后直接向content_scripts通信

九、打包插件

到这一步了,我们所以的插件需求基本完成了,各种通信也都实现了,各种需求也差不多了,该打包了

  1. 打开你的扩展程序
  2. 点击打包扩展程序按钮

在这里插入图片描述

  1. 选择你的文件夹
  2. 点击打包就行

打包之后会提示生成的文件

在这里插入图片描述

  1. 点击确定即可

十、总结

到此,你从0到1完成了一个谷歌浏览器插件的开发与打包,你已经完美了。

但是谷歌插件里面的东西还很多,这个只是浅显的开发一个插件,涉及到的API等在后面的文章在一步步的完善,不积硅步,无以至千里

参考
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

gqkmiss

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值